autocompletelazarustexsynedit

How to use the TSynCompletion and TSynAutoComplete components with SynEdit for TeX?


I want to create a simple TeX/LaTeX editor with Lazarus and SynEdit.

The TSynTeXSyn syntax highlighter highlights the TeX syntax pretty well.

Now I'd like some sort of code completion. Tried to use TSynCompletion and TSynAutoComplete components but they seem to stick with Pascal and other standard programming languages that don't count with a non-letter (i. e. backslash) as a part of a word to be completed.

(I plan the auto-complete list to be basically user defined (by collecting commands/macros from the TeX code and pressing a shortcut or by manually editing the command list). It's nearly impossible for me to take the TeX source and re-write it to be able to see all available macros at the insertion point, which would be nice but I'm not going into that.)

I tried to assign a list with all items starting with a backslash to the ItemList property of the TSynAutoComplete component but that gave me one more backslash after completion (not counting the first backslash as a part of the unfinished prefix and adding another as a part of the list item).

I tried to assign a list without backslashes and that works but it would complete the words anywhere in the text, regardless if a backslash precedes or not.

One solution would be to hack the SynEdit code, make a fork and add backslash into letters for the completion purposes. But I'm not sure that's what I want. It would take even two or more following commands and replace them with one single command that the user chose.

I'd like SynEdit to have an option to type "\" so that the autocomplete window pops up but lets the backslash to be written. Then, as the user types, to let it search for the right term. Then, as the user selects the right command, to overwrite the whole word, including the opening backslash but not any following command to the right.

Do you see a path to achieve this? How would this be complicated?

Can the TSynCompletion external events help me?


Solution

  • Why this doesn't work

    TSynCompletion tokenizer is not tweakable and it's based on an internal procedure that separates the identifiers according to the ASCII identifier chars (a-z, A-Z, _, so it excludes the problematic backslash that should be took as an identifier character).

    The function I talk about is

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

    from the unit SynCompletion

    Resolution

    As you noted in the Q, some events are available and can be used to adjust the result of the completion.

    In a first time Assign the OnCodeCompletion event. Goto the empty method generated for the event and type the following code.

    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;  
    

    In case this would not be clear:

    hit ctrl + space

    accept proposal