Tagbar with BSPWM - new instance doesn't connect

I’m adding a snippet from the i3 module (https://github.com/Delapouite/kakoune-i3/blob/master/i3.kak) and for the life of me I can’t figure out what’s wrong:

define-command -hidden -params 1.. bspwm-new-impl %{
  evaluate-commands %sh{
    if [ -z "$kak_opt_termcmd" ]; then
      echo "echo -markup '{Error}termcmd option is not set'"
      exit
    fi
    bspwm_split="$1"
    shift
    # Clone the window with the same buffer, on the same line.
    kakoune_args="-e 'execute-keys $@ :buffer <space> %val{buffile} <ret> %val{cursor_line} g'"
    {
      exec $kak_opt_termcmd "kak -c $kak_session $kakoune_args"
    } < /dev/null > /dev/null 2>&1 &
  }
}

Running bspw-new-impl temp works ok. It’s spawns a new terminal with a Kakoune instance. The problem is that it doesn’t connect to the existing session. That means it also can’t open the same buffer and move to the proper line.

Also, what does the shift line do?

Thank you

I can’t immediately see what might be wrong, but kak -c $kak_session is the bit that’s supposed to make Kakoune connect to the existing session when it launches. Perhaps you can add a line just before the exec like:

echo $kak_opt_termcmd "kak -c $kak_session $kakoune_args" > /tmp/debug

…then run the command and check /tmp/debug to see if it looks the way you expect?

As for shift, it drops the first command-line argument and shuffles all the rest along. For example, take this script:

#!/bin/sh
echo First three args: $1 $2 $3

echo Shifting...
shift

echo First three args: $1 $2 $3

If I save it as example.sh and run it with some arguments:

$ /bin/sh example.sh a b c d
First three args: a b c
Shifting...
First three args: b c d

The original i3-new-impl command takes a split-type as the first argument, and the rest of the arguments are the command to run. The command saves a copy of the first argument as i3_split and then executes shift to remove it from the argument list, so it can use $@ to refer to “all the remaining arguments” without having to name them individually.

Thank you for your answer. The output looks fine:

sakura -e sh -c kak -c 2059 -e 'execute-keys  :buffer <space> %val{buffile} <ret> %val{cursor_line} g'

I’ve noticed that it fails because I’m using sakura as terminal emulator. In order to sakura to properly parse the args passed to the sh one has to call it like so:

sakura -e sh -c \'ranger /home\'

Which is confusing. With all the layers of shells and quoting I don’t know how to properly implement it in Kakoune. I’m going to experiment and hopefully find a way.

Kakoune’s terminal-detection code uses sakura -x if it finds sakura installed, so that might be worth a try.

@Screwtapello Oh… so it’s -x without the sh -c. How do I print information about the termcmd option from the editor? How would I access that docstring? That’s some useful info.

So does Kakoune go through all possible terminals and uses the first one from that list, that would work?

I also had to change %val{buffile} to $kak_buffile and %val{cursor_line} to $kak_cursor_line. I know that’s because that way Kakoune expands those values before calling the command.

So the final code that works:

# See x11.kak to see its options (like termcmd).
hook global ModuleLoaded x11 %{
    set-option global termcmd "sakura -x"
}
 
define-command -hidden -params 1.. bspwm-new-impl %{
  evaluate-commands %sh{
    if [ -z "$kak_opt_termcmd" ]; then
      echo "echo -markup '{Error}termcmd option is not set'"
      exit
    fi
    bspwm_split="$1"
    shift
    # Clone the window with the same buffer, on the same line.
    kakoune_args="-e 'execute-keys $@ :buffer <space> $kak_buffile <ret> $kak_cursor_line g'"
    {
      # echo $kak_opt_termcmd "kak -c $kak_session $kakoune_args" > /tmp/debug
      exec $kak_opt_termcmd "kak -c $kak_session $kakoune_args"
    } < /dev/null > /dev/null 2>&1 &
  }
}

edit: some more info

How do I print information about the termcmd option from the editor?

You can view the current value of an option with:

:echo %opt{termcmd}

…or, if the value is too big to fit legibly in the status line, you can:

:echo -debug %opt{termcmd}

…and then go check the *debug* buffer to see the result.

How would I access that docstring?

At least by default, once you get as far as:

:set-option

…then Kakoune will show a popup containing brief documentation for the set-option command. Once you get as far as:

:set-option global termcmd

…then the docstring for the option is included in the popup. For me, it looks like this:

╭──────────────────────────────────────┤set-option├───────────────────────────────────────╮
│ set-option [<switches>] <scope> <name> <value>: set option <name> in <scope> to <value> │
│ <scope> can be global, buffer, window, or current which refers to the narrowest scope   │
│ the option is set in                                                                    │
│ termcmd:                                                                                │
│     [str] - shell command run to spawn a new terminal                                   │
│     A shell command is appended to the one set in this option at runtime                │
│ Aliases: set                                                                            │
│ Switches:                                                                               │
│     -add  add to option rather than replacing it                                        │
╰─────────────────────────────────────────────────────────────────────────────────────────╯

So does Kakoune go through all possible terminals and uses the first one from that list, that would work?

By default, yeah. But sometimes people have multiple terminals installed for whatever reason, or their preferences don’t exactly match the order given, so feel free to override it yourself.

Yeah, that looked weird to me, but the original i3wm plugin you linked to did the same thing, and you were complaining about Kakoune connecting to the wrong session, not opening the wrong file, so I figured it wasn’t the underlying problem.

Ok, thank you :slight_smile:

I didn’t complain about moving to the specific buffer and setting the active line because I wanted to take it step by step. Without connecting to the original server I couldn’t have know that this fails. I’ve figured it out thanks to your idea of outputting the command into /tmp/debug.

Anyway, thank you for your help! Everything works now.