如何使 TSynEdit 的 Wordwrap 与 TMemo 相同?

Edw*_*Yip 7 delphi synedit delphi-xe4

我将 TSynEdit 用作更用户友好的 TMemo,主要用于高级快捷方式、UNDO/REDO 等。

其他一切正常,除了自动换行行为,请检查下面附加的屏幕截图,SynEdit 在最左侧显示一个奇怪的空间。

如何避免这种情况并使其看起来像 TMemo?

在此处输入图片说明

TSynEdit 的关键属性设置:

    synEdit1.UseCodeFolding := False;
    synEdit1.Options := [eoAutoIndent, eoDragDropEditing, eoEnhanceEndKey, 
eoGroupUndo, eoScrollPastEol, eoSmartTabDelete, 
eoSmartTabs, eoTabsToSpaces];
      synEdit1.ScrollBars := ssVertical;
      synEdit1.TabWidth := 4;
      synEdit1.WantTabs := True;
      synEdit1.WordWrap := True;
      synEdit1.FontSmoothing := fsmNone;
Run Code Online (Sandbox Code Playgroud)

Mar*_*ynA 4

这不是对问题的完整、经过测试的答案,但可以为有决心的读者提供功能解决方案的起点。

TSynEdit 的自动换行行为由其当前的 TSynWordWrapPlugin. 默认插件在 SynEditWordWrap.Pas 中定义,并包含过程TSynWordWrapPlugin.WrapLines方法,从我昨天使用 D10.2.3 GetIt Manager 下载的版本中的第 512 行开始。

从第 560 行开始,有一个代码块,据我所知,它占了每个换行行开头的空间,如 q 所示:

      if Editor.IsWordBreakChar(vRunner^) then
      begin
        vRowEnd := vRunner;
        break;
      end;
      Dec(vRunner);
Run Code Online (Sandbox Code Playgroud)

vRunnervRowEnd是该方法中使用的许多 PWideChar 变量之一WrapLines

观察这段代码的行为,该代码位于一个while循环内(正在寻找进行自动换行的位置),它会进行操作,以便当Editor.IsWordBreakChar(vRunner^)返回 true 时,vRunner 指针已经向后移动经过分词字符,这这就是为什么它(空格)最终出现在下一行,导致OP指出的问题。

将代码更改为

      if Editor.IsWordBreakChar(vRunner^) then
      begin
        {ma} Inc(vRunner);  //  WARNING: not fully tested
        vRowEnd := vRunner;
        break;
      end;
      Dec(vRunner);
Run Code Online (Sandbox Code Playgroud)

强制 vRunner 指针向前经过分词符,以便空格包含在行尾而不是下一行的开头,因此 SynEdit 然后像标准 TMemo 一样显示其换行文本。

就我个人而言,我不会使用此更改,而是会看看是否可以说服 SynEdit 开发人员提供官方解决方案。如果我确实使用上面显示的更改,我当然不会通过更改 SynEditWordWrap.Pas 的源来做到这一点,我会通过编写替换来做到这一点,TSynWordWrapPlugin并且我将包括一个检查,以确保inc(vRunner)不超出的有效范围缓冲区用于进行自动换行。