Easy way to loop through phantom selections

I want to share some lines of code I wrote to make use of phantom selections.

Basically, I think we usually want to use this plugin to write similar lines, like multiple includes or a bunch of if/else statements. I wanted to create a script that would allow me to instantly jump from having multiple selections to being with only one while keeping the rest phantom. I also wanted to be able to switch between them with <tab>. At the end, I should be able to return to the state I was at the beginning.

One important aspect is that I use <tab> for completitions, and obviously I want to continue using it. This means that if an autocomplete menu spawned I should be able to switch between completitions with <tab> instead of switching to the next phantom selection (unless I close the menu).

Here’s the code.

define-command -hidden -override -docstring "Creates a phantom group of selections" \
    phantom-group %{
        phantom-selection-add-selection
        map buffer normal <tab>   ': phantom-selection-iterate-next<ret>'
        map buffer insert <tab>   '<esc>: phantom-selection-iterate-next<ret>i'
        map buffer normal <s-tab> ': phantom-selection-iterate-prev<ret>'
        map buffer insert <s-tab> '<esc>: phantom-selection-iterate-prev<ret>i'
        map buffer normal <c-g>   ': phantom-ungroup<ret>'
        map buffer insert <c-g>   '<esc>: phantom-ungroup<ret>i'
    }
    define-command -hidden -override -docstring "Removes a phantom group of selections" \
    phantom-ungroup %{
        phantom-selection-select-all
        phantom-selection-clear
        unmap buffer normal <tab>   ': phantom-selection-iterate-next<ret>'
        map   buffer insert <tab>   '<tab>'
        unmap buffer normal <s-tab> ': phantom-selection-iterate-prev<ret>'
        unmap buffer insert <s-tab> '<esc>: phantom-selection-iterate-prev<ret>i'
        unmap buffer normal <c-g>   ': phantom-ungroup<ret>'
        unmap buffer insert <c-g>   '<esc>: phantom-ungroup<ret>i'
    }
    map global normal <c-g>  ': phantom-group<ret><space>'
    map global insert <c-g>  '<a-;>: phantom-group<ret><a-;><space>'

I get the expected behavior by pressing <c-g> (g stands for group) either in normal or insert mode. When I’m done I can press <c-g> again to continue writing/modifying all of the selections.

All the mappings are done at the buffer level because the <tab> mapping for autocompletition happens at the window level. Therefore, the precedence of scopes allows us to have a great behavior.

Of course, this plugin can be used for a lot of things, but because I think a lot of people may be interested in this feature, I posted it here. Once again, I’m a new user of kakoune so feel free to criticize my code :slight_smile:.

3 Likes

Thanks for sharing useredsa.
I never thought about using <tab> to move between selections before but seeing it now it makes perfect sense. As you use it to go from a field to the next one in a form, the usage feels the same.

I’ll think about it and how it can be merged with the regular rotations keys ( and )

I wanted to make it behave the same way as placeholders in snippets.

You can count the selections to use rotate or the phantom selections.