如何让 TSynEdit 的 Wordwrap 和 TMemo 的一样?

How to make TSynEdit's Wordwrap same as TMemo's?

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

其他都正常,除了自动换行,请查看下面的截图,SynEdit 有一个奇怪的 space 显示在最左边。

如何避免这种情况并使其看起来像 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;

这不是一个完整的、经过测试的问题答案,但可以提供确定的答案 reader 功能解决方案的跳转点。

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

从第 560 行开始有一段代码,据我所知, 如 q:

所示,说明每个换行开头的 space
      if Editor.IsWordBreakChar(vRunner^) then
      begin
        vRowEnd := vRunner;
        break;
      end;
      Dec(vRunner);

vRunnervRowEndWrapLines 方法中使用的许多 PWideChar 变量之一。

观察这段代码的行为,它在 while 循环内(正在寻找一个进行自动换行的地方),它运行 这样当 Editor.IsWordBreakChar(vRunner^) returns 为真时,vRunner 指针 已经向后移过分词字符,这就是它(space)结束的原因 在下一行,导致 OP 指出的问题。

将代码更改为

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

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

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