如何将 TSynCompletion 和 TSynAutoComplete 组件与 SynEdit for TeX 一起使用?

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

我想用 Lazarus 和 SynEdit 创建一个简单的 TeX/LaTeX 编辑器。

TSynTeXSyn 语法荧光笔很好地突出了 TeX 语法。

现在我想要某种代码完成。尝试使用 TSynCompletion 和 TSynAutoComplete 组件,但它们似乎坚持使用 Pascal 和其他标准编程语言,这些语言不能将非字母(即反斜杠)作为要完成的单词的一部分。

(我计划自动完成列表基本上是用户定义的(通过从 TeX 代码中收集 commands/macros 并按快捷键或手动编辑命令列表)。我几乎不可能接受TeX 源代码并重写它以便能够在插入点看到所有可用的宏,这很好,但我不打算讨论它。)

我试图将所有项目都以反斜杠开头的列表分配给 TSynAutoComplete 组件的 ItemList 属性,但这在完成后给了我一个反斜杠(不包括第一个反斜杠作为未完成的前缀并添加另一个作为列表项的一部分)。

我尝试分配一个没有反斜杠的列表,但它可以完成文本中的任何位置的单词,无论前面是否有反斜杠。

一种解决方案是破解 SynEdit 代码,进行分叉并在字母中添加反斜杠以完成目的。但我不确定这就是我想要的。它甚至需要两个或更多的后续命令,并将它们替换为用户选择的一个命令。

我希望 SynEdit 有一个选项来键入“\”,以便自动完成 window 弹出,但允许写入反斜杠。然后,当用户输入时,让它搜索正确的术语。然后,当用户选择正确的命令时,覆盖整个单词,包括开头的反斜杠,但不包括右侧的任何后续命令。

你看到实现这一目标的途径了吗?这怎么会很复杂?

TSynCompletion 外部事件可以帮助我吗?

为什么这不起作用

TSynCompletion 分词器不可调整,它基于根据 ASCII 标识符字符(a-z、A-Z、_,因此它排除了有问题的反斜杠)分隔标识符的内部过程应将其视为标识符字符)。

我说的功能是

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;  

如果不清楚:

  • 检查光标之前的标识符之前是否可以有内容。
  • 如果是,则获取位于光标之前的标识符之前的字符。
  • 如果这个字符是反斜杠,那么我们修改默认分词器找到的变量(将反斜杠添加到源中并减少源开始位置)。
  • 一旦我们的值被修补,完成工作正常: