2015-08-01 43 views
1

Я хочу создать простой редактор TeX/LaTeX с Lazarus и SynEdit.Как использовать компоненты TSynCompletion и TSynAutoComplete с помощью SynEdit для TeX?

Синтаксис синтаксиса TSynTeXSyn подчеркивает синтаксис TeX довольно хорошо.

Теперь я хотел бы, чтобы какой-то код был завершен. Пытался использовать компоненты TSynCompletion и TSynAutoComplete, но они, похоже, придерживаются Pascal и других стандартных языков программирования, которые не учитываются при отсутствии буквы (например, обратной косой черты) как части слова, которое должно быть завершено.

(Я планирую, чтобы список автозаполнения был в основном определяемым пользователем (путем сбора команд/макросов из кода TeX и нажатия ярлыка или путем ручного редактирования списка команд). Мне почти невозможно взять источник TeX и перезаписать его, чтобы иметь возможность видеть все доступные макросы в точке ввода, что было бы неплохо, но я не собираюсь в этом.)

Я попытался назначить список со всеми элементами, начиная с обратной косой черты свойство ItemList компонента TSynAutoComplete, но это дало мне еще одну обратную косую черту после завершения (не считая первую обратную косую черту как часть недоделанного префикса и добавляя другую как часть элемента списка).

Я попытался назначить список без обратных косых черт и который работает, но он будет заполнять слова в любом месте текста, независимо от того, предшествует ли обратная косая черта или нет.

Одним из решений было бы взломать код SynEdit, сделать вилку и добавить обратную косую черту в буквы для целей завершения. Но я не уверен, что это то, чего я хочу. Требуется две или несколько следующих команд и заменить их одной единственной командой, которую пользователь выбрал.

Я бы хотел, чтобы SynEdit имел возможность ввести «\», чтобы окно автозаполнения всплывало, но позволяет писать обратную косую черту. Затем, по мере того, как пользователь вводит текст, чтобы он искал правильный термин. Затем, когда пользователь выбирает правильную команду, чтобы переписать все слово, включая обратную косую черту, но не любую следующую команду справа.

Вы видите путь для достижения этого? Как это будет сложно?

Могут ли внешние события TSynCompletion помочь мне?

ответ

2

Почему это не работает

TSynCompletion токенизатор не настраиваемый и она основана на внутреннюю процедуре, которая отделяет идентификаторы в соответствии с символами идентификатора ASCII (AZ, AZ, _, так что исключает проблематично обратную косую черту, которая должна восприниматься как символ идентификатора).

Функция Я говорю о том,

function IsIdentifierChar(p: PChar): boolean; inline; 

из блока SynCompletion

Разрешение

Как отмечалось в Q, некоторые события доступны и могут быть использованы для настройки результат завершения.

В первый раз Присвойте событие OnCodeCompletion. Откройте пустой метод, сгенерированный для события, и введите следующий код.

procedure TForm1.SynCompletion1CodeCompletion(var Value: string; 
    SourceValue: string; var SourceStart, SourceEnd: TPoint; KeyChar: TUTF8Char; 
    Shift: TShiftState); 
begin 
    if SourceStart.x > 0 then 
    begin 
    if SynEdit1.Lines[SourceStart.y - 1][SourceStart.x-1] = '\' then 
    begin 
     SourceStart.x -= 1; 
     SourceValue := '\' + SourceValue; 
    end; 
    end; 
end; 

В случае, если это не было бы ясно:

  • проверьте, может быть что-то перед идентификатором, расположенного перед курсором.
  • если это так, получите символ, расположенный перед идентификатором, расположенным перед курсором.
  • Если этот символ является обратным слэшем, тогда мы модифицируем переменные, найденные стандартным токенизатором (добавьте обратную косую черту к источнику и уменьшите начальную позицию источника).
  • После того, как наши ценности исправленных, завершение работает отлично:

hit ctrl + space

accept proposal

+0

Отлично! Я думал, что нужно задействовать другие события, особенно события OnExecute и OnSearchPosition. Но свойство 'CurrentString' может быть легко изменено событием' OnCodeCompletion', а остальное - автоматически. –

+0

Двойной проверил это и заметил, что все еще есть проблема с прикованными командами. Если у вас есть, скажем, '\ alpha \ beta \ ga' и попытайтесь завершить' \ gamma', тогда будет выбрана '\ alpha', и вы замените все три команды. Решено, что, сопоставляя только последнюю команду и изменяя позицию соответственно в событиях OnExecute и OnSearchPosition. –

+1

Извините за угловой футляр, но факт в том, что я вообще не знаю TeX. По крайней мере, у вас есть базовое представление о том, как действовать. Другой способ решить вашу проблему был бы в подклассе TSynCompletion, но метод, который должен быть переопределен, к сожалению, не является виртуальным ... –