gpt4 book ai didi

macos - NSTextStorageDelegate 的 textStorage(_,willProcessEditing :, range :, changeInLength:) 移动选择

转载 作者:行者123 更新时间:2023-12-05 01:32:12 28 4
gpt4 key购买 nike

我正在尝试实现一个语法着色文本编辑器,它还可以为您在新行的开头插入空格或用文本附件替换文本。

在先前的实现遇到撤消问题后再次仔细阅读文档后,似乎推荐的瓶颈是 NSTextStorageDelegate 的 textStorage(_,willProcessEditing:,range:,changeInLength:) 方法(它指出 Delegates can change the characters or attributes. ,而 didProcessEditing说我只能改变属性)。这很好用,除了每当我实际更改属性或文本时,文本插入标记都会移动到我修改的任何文本范围的末尾(因此,如果我更改整行的样式,光标会移到行尾)。

有谁知道我错过了哪些额外的电话告诉 NSTextStorage/NSTextView 不要搞砸插入标记?此外,一旦我插入文本,我可能必须告诉它移动插入标记以说明我插入的文本。

注:我看过Modifying NSTextStorage causes insertion point to move to the end of the line ,但假设我是 NSTextStorage 的子类,所以我不能在那里使用解决方案(并且宁愿不子类 NSTextStorage,因为它是一个半抽象的子类,如果我将它子类化,我会失去 Apple 类的某些行为)。

最佳答案

我找到了问题的根源。

并且基于 Cocoa 框架固有的原因,而不是单纯的变通方法,唯一能够稳健工作的解决方案。 (请注意,可能至少还有另一种基于大量快速修复的亚稳态方法会产生类似的结果,但随着亚稳态替代方案的发展,这将非常脆弱,需要大量的努力来维护。)

  • TL;DR 问题: NSTextStorage收藏 edited调用并组合范围,从用户编辑的更改(例如插入)开始,然后添加 addAttributes(_:range:) 中的所有范围在突出显示期间调用。
  • TL;DR 解决方案:从 textDidChange(_:) 执行突出显示只。

  • 细节

    What happens when you type and change style

    这仅适用于单个 processEditing()运行,都在 NSTextStorage子类和 NSTextStorageDelegate回调。

    我发现执行突出显示的唯一安全方法是 Hook NSText.didChangeNotification或实现 NSTextDelegate.textDidChange(_:) .

    根据@Willeke 对 OP 问题的评论,这是布局通过后执行更改的最佳位置。但与评论线程相反,设置回 NSText.selectedRange还不够。在插入符号移开后,您不会注意到后修复选择的问题,直到
  • 您突出显示整个文本 block ,
  • 跨越多行,
  • 超出 ScrollView 的可见 (NSClipView) 边界。

  • 在这种罕见的情况下,大多数击键都会使 ScrollView 抖动或弹跳。但是没有针对此的额外快速修复。我试过。既不阻止从 NSLayoutManager 中的私有(private) API 发送滚动命令也不会通过从 NSTextView 覆盖所有带有“滚动”的方法来避免滚动子类效果很好。当然,您可以完全停止滚动到插入点,但是没有这样的运气得到一个仅在执行突出显示时不会滚动的可靠算法。
    didChangeNotification方法在我和我的应用程序的测试人员能够提出的所有情况下都能可靠地工作(包括像滚动文本这样奇怪的崩溃情况,然后在动画期间用更短的字符串替换字符串 - 是的,试着弄清楚报告无效字形生成的崩溃日志中的那种东西......)。

    这种方法之所以有效,是因为它执行了 2 次字形生成 channel :
  • 一次通过编辑范围,在使用 NSRange 键入每个键击的情况下长度为 1,发送 edited通知[.editedCharacters, .editedAttributes] ,前者负责移动插入符号;
  • 对受语法高亮影响的任何范围的另一次传递,发送 edited通知 [.editedAttributes]仅,因此根本不影响插入符号的位置。

  • 更多细节

    如果您想更多地了解问题的根源,我将更多我的研究、不同的方法和解决方案的细节放在更长的博客文章中以供引用。不过,这就是解决方案本身。 http://christiantietze.de/posts/2017/11/syntax-highlight-nstextstorage-insertion-point-change/

    关于macos - NSTextStorageDelegate 的 textStorage(_,willProcessEditing :, range :, changeInLength:) 移动选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45126948/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com