Select next object

I’m using the following mappings to select inside the next object:

define-command -override -hidden select-next-param %{
    execute-keys -save-regs '/' '/[(,]<ret>l<a-i>u'
}

map global user "'" "f'<a-i>'" -docstring "select inside next single quotes"
map global user '"' 'f"<a-i>"' -docstring "select inside next double quotes"
map global user ')' 'f(<a-i>)' -docstring "select inside next parentheses"
map global user ']' 'f[<a-i>]' -docstring "select inside next brackets"
map global user '}' 'f{<a-i>}' -docstring "select inside next braces"
map global user '>' 'f<lt><a-i><gt>' -docstring "select inside next angles"
map global user 'u' ': select-next-param<ret>' -docstring "select next argument"

A common use-case is selecting the text inside a string when the cursor is before the string.
With Vim I would use e.g. ci" to change a string even if the cursor is before the opening double quote, but with Kakoune <a-i>" selects the wrong thing unless the cursor is inside the string. So I mapped ," to select the next string.

3 Likes

I will be using this immediately, I found the exact same issue coming from Vim and never got used to the kakoune way.

There are plugins available from @Delapouite and me.

They do the same, but implementation is different.

It looks like these plugins work by first searching for the end of the object. For example, to select the next parentheses they use

f)<a-a>)

instead of

f(<a-a>)

So these plugins have the advantage of working even if the cursor is inside the parentheses, and more importantly you can iterate through all parentheses at all levels of nesting by using the mapping repeatedly.

But nested parentheses will be selected before selecting the parentheses surrounding them (e.g. (a) then (b) then ((a)+(b)) in ((a)+(b)), so if you just want to select the next outer parentheses you’ll need to use the mapping multiple times instead of just once.

To fix the selection order to select the surrounding parentheses first (e.g. first ((a)+(b)) then (a) then (b) in ((a)+(b))), use:

<a-:><a-;>f(<a-a>)

So I guess the most powerful way to iterate though all parentheses would be using one mapping for f(<a-a>) (select next parentheses without descending into current selection) and another mapping for <a-:><a-;>f(<a-a>) (select next parentheses, descending into current selection if it has nested parentheses).

1 Like