Closed fenduru closed 10 years ago
I've always thought this might be useful. I think gH
would be a good sequence to assign this command to. It should reuse the most recent search pattern.
I'm working on this right now. Do you think it would be reasonable to use the existing gh
, and use the vi_search regions if it exists, otherwise fall back to current behavior? I don't see too much of a use case for having both vi_search regions and select mode selections visible at the same time.
vi_search
regions are erased after they aren't needed any more. The number of hits in the buffer may have changed between the time they were created and the moment the user wants to reuse them.
Besides, I think it wouldn't be obvious what happened if, after pressing gh
, a bunch of regions were highlighted instantly. I think it's better to be more explicit about requesting the last search pattern used, hence gH
.
The way I was thinking was that if there are vi_search selections, these will be used when you enter select mode, and you would still use j
, k
, A
, etc to choose which ones get selected. This way there is only one paradigm for managing selections in select mode, just different "sources" (this is already the case depending on if your cursor is on a word, or if you have a visual selection. We would add another one if there are search results).
I see what you mean now, but I'm still unconvinced -- I'd find it confusing. The caret could have traveled away from one of the vi_search
regions, so when you pressed gh
, it would jump to one of them (which one, BTW?). I'd say let's start simple and try a first implementation with gH
that selects all of them and go from there? Allowing j
, k
and A
to work in that case would require a separate mode, as far as I can tell.
Okay, will do. I already have most of the "select all vi_search selections" stuff done, but I'm still not super familiar with this code base. There seems to be quite a few places that keys are listed, so I'm not sure how to go about adding a new hotkey. Any suggestions?
(I need to work on naming and terminology, but bear with me...)
To add a new 'command' you need to:
I think that's all, but holler if you need help.
EDITED
For what its worth, the amount of places that need editing in order to add a fairly simple action seems to be a bit much. Why does there need to be so much indirection? I feel like most things could be done using normal keymapping
{ "keys": ["g", "H"], "command": "vi_select_search_results", "args": {"mode": "normal"}}
And if you have a particular key that does multiple things:
{ "keys": ["A"], "command": "vi_append_to_line", "args": {"mode": "normal"}},
{ "keys": ["A"], "command": "vi_select_all", "args": {"mode": "select"}}
Then, in the base class that vi_commands subclass, you could filter based on whether or not you're in the right mode.
That was more or less the way it worked before, but then you could not have user mappings. In order to have flexible mappings, Vintageous needs to know about every key press. That's also very important for commands that require input.
I agree there's quite some indirection, but every time I tried to simplify things I would hit a dead end. I'd be happy to be enlightened about a better way, though.
I think we can close this, btw.
What roadblocks have you run into (just so I can be thinking about all of the different issues).
Just brainstorming a bit, I think you could do something like this:
c
which calls vi_change
(or whatever it is actually called).$
which calls vi_line_end_motion
There would need to be some special handling for numbers, where you would save a buffer of number key-presses, but that shouldn't be that bad.
This would allow fairly complex key-mappings without doing much more than using the built-in keymapping system.
Having remapping would be hard though. Maybe there is a way to hook into the underlying system and simulate keypresses for remapping? (Not sure about this one)
(Writing from memory here.)
- Press c which calls vi_change (or whatever it is actually called).
- vi_change registers a 'motion callback'
- Press $ which calls vi_line_end_motion
- vi_line_end_motion sees that there is another command that needs a motion, so it calls the callback
That may work more or less ok for a few commands, but what if you wanted to
have a sequence like ys/foo<cr>"
(from the surround plugin)? You'd need to
load a second set of key bindings and they may or may not work depending on
ordering.
Also, Vim waits forever on incomplete commands (unless it's holding an ambiguous mapping, in which case uses a timeout), but I believe ST always times out (or used to, anyway).
There would need to be some special handling for numbers, where you would save a buffer of number key-presses, but that shouldn't be that bad.
Don't forget registers and commands that accept input. You'd have a hard time
trying to interpert "ad/foo
using just normal key bindings. What about repeat,
redo and macros? You cannot run the command until it's ready, and although
Vintageous now does a better job of keeping the caret in a sensible place, it
should actually be able to see the future carets and remember them. Vim seems
to ignore motions when placing the caret, so when you redo or undo, you are
left at the beginning of the corresponding operator's target region. This is
currently one of the toughest problems in Vintageous. I think it could maybe
be solved by looking at the future selection regions, but that means more
state and processing ahead of time.
Having remapping would be hard though. Maybe there is a way to hook into the underlying system and simulate keypresses for remapping? (Not sure about this one)
Enabling custom mappings was the whole point of the recent rewrite. You cannot have them if you don't know which keys were pressed. Also, you must control key biding contexts too.
And you need the actual key names to display coherent feedback and to map
stuff, like :nmap dx i"__FOOBAR__<esc>ea"<esc>
, that should work now.
I haven't kept notes, but there's quite a few places where emulating Vim demands knowing the exact keys the user has pressed. That said, I'm sure there's room for a lot of improvement.
The area that seems to lend itself to further refactoring is the disconnect between defining a command in _cmddefs.py and updating the command just before it's going to be run, in either _viactions.py or _vimotions.py. It may be possible to unify both steps into a single one, but I think I ran into difficulties as well last time I tried.
It also looks possible to do away with defining keys for every mode if the command definition itself could return the actual definition for a given mode. That should also keep things tidier.
Yeah that all makes sense (not totally sure what you mean by the last comment though). I agree that cleaning up the cmd_defs stuff into one location would be nice.
Also there seems to be another redirection (at least in the commands I saw) where the key binds to vi_function_name
which "prepares" the command, then sends it to _vi_function_name
.
I would love to see the keybinds that let vintageous listen to every keypress, then one hash that maps from key combination to command (and includes information like mode, etc in this hash).
Yeah that all makes sense (not totally sure what you mean by the last comment though).
In keys.py, you now have to map a sequence (like gg
) to a command definition by mode. This means you need to declare keys for every single mode. I think it's possible to declare only all known sequences to the ideal command definition, and then the command definition would know which data to use for each mode or, if it wasn't a legal sequence for the current mode, simply a _missing
command.
I think your last paragraph summarizes the idea, but I believe some restrictions imposed by the edit
object in the ST api make it hard to make it that simple.
Often times I want to search for a pattern using / (slash), which very neatly highlights all of the matches. I would then like to select all of those highlighted matches (as in select mode), however select mode only lets you choose words or visual-mode selections.