How can I iterate over selections and their descriptions?

For issue #3336, I want to take each selection and pipe it to lintcmd. However, a linter will return its line-numbers relative to the start of the selection, not the start of the buffer, so I need to rewrite the line and column-numbers in the output.

Sounds simple enough - as well as processing $kak_selections, I’ll also grab $kak_selections_desc and then I’ll know where each selection originally came from! Except, it’s not actually that simple:

  • Start Kakoune with seq 1 3 | kak -n
  • Select all the digits in the buffer: %s\d<ret>
  • Examine the contents of each selection: :echo %val{selections}
    • yep, looks good: '1' '2' '3'
  • Examine the coordinates of each selection: :echo %val{selections_desc}

Uh oh:

3.1,3.1 1.1,1.1 2.1,2.1

…that is, %val{selections_desc} always starts with the primary selection, no matter where it is in the document, while %val{selections} seems to be in document order, regardless of which is the primary.

How can I get selections and descriptions in a consistent order? I know if I save a mark to a register, it stores the index of the main selection… but I don’t know if there’s any guarantees about the overall order of selections.

Hmm maybe this works:

eval %sh{ echo select $(printf '%s\n' $kak_selections_desc | sort -n -t .) }

After this %val{selections_desc} and %val{selections} will be in sync.

1 Like

What are the reasons in the first place for this discrepancy between the two different ordering ? Is there a specific use case that justify it ?

If not, I would say this should be made consistent on C++ part to aleviate the pain on the script side.

I wound up going with this:

evaluate-commands %sh{
    printf "select "
    printf "%s\n" "$kak_selections_desc" |
        tr ' ' '\n' |
        sort -n -t. |
        tr '\n' ' '
}

Possibly that’s over-complicated, but it seems to work.

It might be useful to know which selection is the primary; there’s no %val{primary_selection} expansion or any other way to know which it is. I can’t think of a use off the top of my head, though…