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

SelectionChange hook #1821

Open
notramo opened this issue Jan 30, 2018 · 6 comments
Open

SelectionChange hook #1821

notramo opened this issue Jan 30, 2018 · 6 comments

Comments

@notramo
Copy link
Contributor

notramo commented Jan 30, 2018

Use case: #898. When selection cursors/anchors (not the buffer content) change, the user can save the selections to a register using this hook:

hook buffer SelectionChange %{
  # Save selections to the 's' register
  execute-keys %{
    \" s Z
}

It can be restored with "sz.

@occivink
Copy link
Contributor

The performance concerns of #912 probably apply here too (even more so, in fact).

@notramo
Copy link
Contributor Author

notramo commented Jan 30, 2018

I think, this wouldn't be slow with this use case.
I currently have a poor solution with NormalKey .*, which is called more often than this hook would be called (e.g. pressing : for prompt mode, or v for changing view). It isn't slow, but requires more wrong hacks, because selection storing registers change every time a key pressed, even if the cursors/anchors aren't modified.

@danr
Copy link
Contributor

danr commented Jan 30, 2018

I think #1747 might be important for this to be performant, consider all the selection changes going on inside exec and execs with -itersel.

@mawww
Copy link
Owner

mawww commented Jan 30, 2018

There should not be performance problems here, as opposed to buffer changes, as you'd still get a single selection change event if you move a thousand multiselections at the same time.

The problem here is that it requires a big change of Kakoune's code so that we can detect whenever the selection is modified. At the moment selections can be changed quite liberally by the code, and we do not have a single point in the code that can be instrumented. This is the same reason why we still dont have the selection undo mechanism that has been requested many times.

I suspect at the moment, you could hook on NormalIdle and check if the selection did indeed change.

@robertmeta
Copy link
Contributor

Sorry to necro this 2018 conversation, but a SelectionChange hook is likely the linchpin of an accessibility plugin. Due to the design of kakoune. With a SelectionChange hook we could simply use selections as the reading cursor, then after a read you could revert back to last selected state.

Is this still a fully dead no-hope issue?

@krobelus
Copy link
Contributor

krobelus commented Jul 20, 2023

after a read you could revert back to last selected state.

you can use selection undo (<a-u> / <a-U>).
If there is still a need for a hook it'd be easy to add:

From 3f6901b55ff3f1221e54f3869c63b13e3a0221f5 Mon Sep 17 00:00:00 2001
From: Johannes Altmanninger <[email protected]>
Date: Thu, 20 Jul 2023 08:01:55 +0200
Subject: [PATCH] SelectionChange hook

This hook triggers whenever the user-visible selection changes.
Like <a-u>, it does not trigger when only the index of the main
selection changes though that could be changed if needed.
---
 doc/pages/changelog.asciidoc | 2 ++
 doc/pages/hooks.asciidoc     | 3 +++
 src/context.cc               | 2 ++
 src/hook_manager.hh          | 2 ++
 src/main.cc                  | 1 +
 5 files changed, 10 insertions(+)

diff --git a/doc/pages/changelog.asciidoc b/doc/pages/changelog.asciidoc
index e9bdf758e..469622207 100644
--- a/doc/pages/changelog.asciidoc
+++ b/doc/pages/changelog.asciidoc
@@ -8,6 +8,8 @@ released versions.
 * `<a-u>` and `<a-U>` now undo/redo selection changes; the previous meaning
   of moving in history tree has been moved to `<c-j>` and `<c-k>`
 
+* New `SelectionChange` hook.
+
 * `%exp{...}` expansions provide flexible quoting for expanded strings
   (as double quoted strings)
 
diff --git a/doc/pages/hooks.asciidoc b/doc/pages/hooks.asciidoc
index 46de91339..6c2b0b3a5 100644
--- a/doc/pages/hooks.asciidoc
+++ b/doc/pages/hooks.asciidoc
@@ -186,6 +186,9 @@ name. Hooks with no description will always use an empty string.
 *ModuleLoaded* `module`::
     Triggered after a module is evaluated by the first `require-module` call
 
+*SelectionChange*::
+    Triggered after a user-visible selection change.
+
 *User* `param`::
     Triggered  via the `trigger-user-hook` command. Provides a way for plugins
     to introduce custom hooks by specifying what *param* would be.
diff --git a/src/context.cc b/src/context.cc
index 0c1b8aadf..a7a055fe5 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -212,6 +212,7 @@ void Context::SelectionHistory::end_edition()
     }
     else
     {
+        m_context.hooks().run_hook(Hook::SelectionChange, "", m_context);
         m_history_id = next_history_id();
         m_history.push_back(std::move(*m_staging));
     }
@@ -248,6 +249,7 @@ void Context::SelectionHistory::undo()
             m_context.change_buffer(destination_buffer, { std::move(select_next) });
     }
     while (selections() == old_selections);
+    m_context.hooks().run_hook(Hook::SelectionChange, "", m_context);
 }
 
 void Context::SelectionHistory::forget_buffer(Buffer& buffer)
diff --git a/src/hook_manager.hh b/src/hook_manager.hh
index 24e88e1ac..ab1325338 100644
--- a/src/hook_manager.hh
+++ b/src/hook_manager.hh
@@ -43,6 +43,7 @@ enum class Hook
     FocusOut,
     GlobalSetOption,
     RuntimeError,
+    SelectionChange,
     PromptIdle,
     NormalIdle,
     NextKeyIdle,
@@ -95,6 +96,7 @@ constexpr auto enum_desc(Meta::Type<Hook>)
         {Hook::ModeChange, "ModeChange"},
         {Hook::RawKey, "RawKey"},
         {Hook::RegisterModified, "RegisterModified"},
+        {Hook::SelectionChange, "SelectionChange"},
         {Hook::WinClose, "WinClose"},
         {Hook::WinCreate, "WinCreate"},
         {Hook::WinDisplay, "WinDisplay"},
diff --git a/src/main.cc b/src/main.cc
index 35afcc7ab..e9cede11c 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -48,6 +48,7 @@ struct {
         "» {+b}<a-u>{} and {+b}<a-U>{} now undo/redo selection changes; "
         "the previous meaning of moving in history tree has been moved to "
         "{+b}<c-j>{} and {+b}<c-k>{}\n"
+        "» {+u}SelectionChange{} hook\n"
         "» {+u}%exp\\{...}{} expansions provide flexible quoting for expanded "
         "strings (as double quoted strings)\n"
         "» {+u}show-matching -previous{} switch\n"
-- 
2.41.0.191.g6ff334181c

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

No branches or pull requests

6 participants