Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command block that restores scroll offsets and selection like Emac Lisp save-excursion #4

Open
DivineDominion opened this issue May 22, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@DivineDominion
Copy link
Contributor

Note: This may not be needed in practice at all. We have to test this.


One feature that Emacs Lisp provides is to jump around in a buffer and read and write text, then restore the context exactly as it was before so that the user doesn't perceive anything. This is called save-excursion.

// Imagine we're in the middle of a long document here, like
// line 500 of 1000.

SaveExcursion {
    Select(LineRange(at: 0)) {
        // ... do stuff on the first line ...
    }
    Select(LineRange(at: buffer.endLocation)) {
        // ... do stuff on the last line line ...
    }
}
 
// At this point, we're at line 500 again and the scroll offset is the same as before

Unlike our Buffer.character(at:), Emacs buffers can't access substrings without moving them into view. There, the buffer is the model, and moving the reading head also moves the scrolled viewport.

NSTextView can show similar behavior when you change characters in one place and attributes in a larger place and the effective range is enlargened; then the NSTextStorage.processEditing() run will move the insertion point:

example
Source and fix: https://christiantietze.de/posts/2017/11/syntax-highlight-nstextstorage-insertion-point-change/

UITextView doesn't have this problem.

@DivineDominion DivineDominion added the enhancement New feature or request label May 22, 2024
@DivineDominion
Copy link
Contributor Author

One possible implementation could be to create snapshots in SaveExcursion and put them onto a stack to then restore after processing has finished. If problematic behavior shows at all, we sadly need to hook into the appropriate delegate functions or notifications to apply this.

  • Notifications: 👍 easy to add without client code having to do anything; 👎 order is not predictable, so we may get the notification before the actual app does, and mess up something.
  • Delegate: 👍 best represents one sequence of actions to do in reaction to a change; 👎 client code has to call this or set this up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant