cursorless icon indicating copy to clipboard operation
cursorless copied to clipboard

Add proper "jump back" command

Open pokey opened this issue 3 years ago • 7 comments

Every time you issue "pre", "post", "take", or "clear", it will capture previous cursor location and keep it up to date

Can use "bounce" or just "back" for this one

Would want to support "bring air back", eg without "to"

pokey avatar Aug 06 '21 10:08 pokey

I vote for this!

tararoys avatar Mar 20 '22 17:03 tararoys

To be clear this would be a special target?

AndrewDant avatar May 06 '22 16:05 AndrewDant

It would be a special mark. Will be best to do as part of https://github.com/cursorless-dev/cursorless/issues/191

pokey avatar May 06 '22 18:05 pokey

Ok actually I take it back. No need to go super general. I'd just get something working for a start.

I'd start by copying https://github.com/cursorless-dev/cursorless/blob/main/src/core/IndividualHatMap.ts

The important thing is to register your ranges with the range updater to ensure that they stay up to date as the document changes. See https://github.com/cursorless-dev/cursorless/blob/main/src/core/IndividualHatMap.ts#L30 to see where it is called there, and also the docs

pokey avatar May 09 '22 22:05 pokey

Some things to keep in mind:

  • Should make this thing a graph component. Can grep for editStyles to see a good example. You may need to give it an init function and call it from extension.ts as well
  • The class should register to listen to all selection changes in order to push them on a stack
  • Prob want stack to have max len
  • It should have a method to pause its listening, which will be used by CommandAction to avoid polluting stack during hacked commands that do a jump
  • The stack should be accessible from command context during command execution so that the top (and potentially below) can be accessed as a mark
  • How do we pop the stack? We somehow would need to detect that we're doing a "take back" command, but currently "take" and "back" would be orthogonal so neither knows it's a "take back". Maybe we could have a special command just called "back" that knows to pop the stack

pokey avatar May 10 '22 06:05 pokey

Heyo @pokey, here's a few notes/questions

Prob want stack to have max len

It should have a method to pause its listening, which will be used by CommandAction to avoid polluting stack during hacked commands that do a jump

❓I'm curious about this one, the description implies that we should use this for just a subset of actions. What in your mind are hacked actions?

The stack should be accessible from command context during command execution so that the top (and potentially below) can be accessed as a mark

How do we pop the stack? We somehow would need to detect that we're doing a "take back" command, but currently "take" and "back" would be orthogonal so neither knows it's a "take back". Maybe we could have a special command just called "back" that knows to pop the stack

✅ / ❓ Makes sense to me. Will we have to check DFA/public on this one? ❓ One thought I have about this is that it might make sense to keep two stacks to allow for movement forwards and backwards, similar to a "undo/redo". ❓Will "back" only pair with certain actions?


Some edge cases to think about:

  • What happens when the code underlying the selection is deleted? Should we keep track of the node ids somewhere and proactively prune the stack? If we go this path, how to we represent that the underlying file has changed to the user? What is the correct behavior?
    • I think we should proactively prune and just tell the user that the previous node is gone and so the command is ambiguous. I don't know if we have a better way to communicate apart from the pop-up in the bottom right.
  • This isn't an undo/redo command level action so we don't need to think about storing the underlying text, just the selection.

Will-Sommers avatar May 10 '22 16:05 Will-Sommers

It should have a method to pause its listening, which will be used by CommandAction to avoid polluting stack during hacked commands that do a jump

❓I'm curious about this one, the description implies that we should use this for just a subset of actions. What in your mind are hacked actions?

What is "this" here? "back" will just be a mark which refers to the previous cursor location, so can be used for any action. The stack of previous cursor locations will be populated by listening for any changes to the selection, no matter where they come from. However, there are certain cases we want to avoid things ending up on the cursor location stack, because the cursor movement is transient. These examples are the "hacked" actions I mentioned, where we move the cursor because there is no properly cursorless way of doing them. For example, today the "copy" action is implemented by moving the cursor, copying, then moving the cursor back. For this case, it is confusing if the location that the cursor moved is on the previous location stack, because from the user's perspective the cursor never moved

make sense?

How do we pop the stack? We somehow would need to detect that we're doing a "take back" command, but currently "take" and "back" would be orthogonal so neither knows it's a "take back". Maybe we could have a special command just called "back" that knows to pop the stack

✅ / ❓ Makes sense to me. Will we have to check DFA/public on this one?

Should have no DFA impact because it's an independent command

❓ One thought I have about this is that it might make sense to keep two stacks to allow for movement forwards and backwards, similar to a "undo/redo".

Two stacks is an interesting idea.

❓Will "back" only pair with certain actions?

So there will be two things: "back" the mark and "back" the command. We might call them two different things tbh. Maybe "last" for the mark, and "back" for the command. The mark can pair with anything because it's just a mark, the command is just a standalone command that moves cursor and pops stack so doesn't really pair with anything

"

Some edge cases to think about:

  • What happens when the code underlying the selection is deleted? Should we keep track of the node ids somewhere and proactively prune the stack? If we go this path, how to we represent that the underlying file has changed to the user? What is the correct behavior?

    • I think we should proactively prune and just tell the user that the previous node is gone and so the command is ambiguous. I don't know if we have a better way to communicate apart from the pop-up in the bottom right.

I'd just let the range updater handle this one for now. If it becomes annoying we can figure out removing from the stack

  • This isn't an undo/redo command level action so we don't need to think about storing the underlying text, just the selection.

Yeah we just keep the range, and let the range updater keep it up to date as the document evolves

pokey avatar May 11 '22 09:05 pokey