How run run selection with shell?

Hi, sometimes I want to debug my shell script quickly, so I want to select some script and run it.

for example, I have the following text:

echo hello
foo="bar"
echo $foo

then I press %, select them, then I run : %sh{ $kak_selection }

kakoune throw no such command

what is the proper way to do it?

When you type a command and hit <ret>, Kakoune follows the following steps:

  • the command is split up into words, according to the quoting rules
  • any expansions like %opt{}, %val{}, or %sh{} are expanded (possibly into multiple words)
  • the first word is taken as the command, any following words are taken as arguments
  • if there’s a command with that name, it is executed and passed the arguments (if any)

In your example:

  • we start with one word, %sh{ $kak_selection }

  • Kakoune launches a shell with $kak_selection set to the contents of the selection, the shell executes it and produces the output:

    hello
    bar
    
  • That output is substituted into the original command. Kakoune doesn’t support backslash-quoting, but if it did, the resulting command might look like:

    "hello\nbar\n"
    
  • Kakoune takes the first word as the command, and there are no following words.

  • Kakoune fails to find a command named hello\nbar\n so it throws a “no such command” error.

The easiest way to solve your problem is to do:

nop %sh{ $kak_selection }

nop is a command that ignores its arguments, and it’s commonly used to execute shell commands and throw away the output.

A smarter thing to do might be:

echo -debug %sh{ $kak_selection }

…so that any output is sent to the *debug* buffer rather than lost entirely. That’s where any stderr output goes, so you’ll probably be checking there anyway.

The best way to solve your problem is probably to use the repl-send-text command. If you’re running Kakoune inside tmux, or if you’re in X11 and have the xdotool command installed, you can run any command in a fresh terminal connected to Kakoune with repl-new:

repl-new /bin/sh

Once you’ve done that and the terminal appears, you can select some text in Kakoune and run :repl-send-text to copy that text and paste it into the REPL terminal, where you can see the output.

If you don’t have X11 and don’t want to use tmux, but you do have Python 3 installed, you might also try my repl-buffer plugin: https://gitlab.com/Screwtapello/kakoune-repl-buffer. It’s a bit more awkward since a Kakoune buffer is not a terminal and some tools don’t like that, but at least you can manage REPL buffers the same way you manage any other Kakoune buffers, and copy/paste output, etc.

1 Like

Thanks very much. I use tmux, and I tried repl-new, it’s the best way to cover my needs.

Hi, do you know how to pass \n to repl-send-text, I want to send exit\n to repl,:

map global normal <c-a-c> ": repl-send-text 'exit\n' <ret>" -docstring "close  new repl pane"

but it will send the literal \n

Kakoune doesn’t support backslash-escaping control characters (or backslash-escaping anything, really) in script. However, when you’re typing at a prompt (including when a mapping or execute-keys is typing on your behalf) you can press <c-v> to have Kakoune type the next key “verbatim” instead of interpreting it. So for example, <c-v><ret> will actually type a <ret> on the command-line, rather than <ret> making Kakoune process the completed command. Try something like:

map global normal <c-a-c> ": repl-send-text 'exit<c-v><ret>'<ret>"

Thanks very much! it works.