How to execute shell commands with the current file name?

I have been using Vim for 2 years now. I am now switching to Kakoune. When I work with my latex files, I have a my Ctrl+Space key mapped to a sh command that will compile the latex file, (like this line in .vimrc);

autocmd FileType tex nnoremap <C-@> :w<Enter>:!xelatex -shell-escape -mode=nonstopmode %<Enter>

or sometimes when I am experimenting or quick prototyping, I compile and run my C codes, via this line in .vimrc

autocmd FileType c nnoremap <C-@> :w<Enter>:!clang -o run % && ./run<Enter>
autocmd FileType java nnoremap <C-@> :w<Enter>:!javac % && java %:r<Enter>

What are their kakrc equivalent? I am very very new to Kakoune and I have no idea what Kakoune specific things like hooks, highlighters, faces etc are. Someone please give me the codes that I can directly yank-paste in my kakrc and get working. And get into docs eventually as I get comfterble.

Also, if you don’t know what .vimrc line meant,

autocmd FileType java if the FileType is java, nnoremap non-recursively map, <C-@> Ctrl+Space to :w<Enter> save the file, and execute :!javac % && java %:r<Enter> where % is the currently open filename and %:r is the filename without the extensions.

A Kakoune “hook” is like a Vim “autocmd”: when a particular event happens with a particular parameter, a particular set of commands get run.

In particular, autocmd FileType blah somecommand is like:

hook global WinSetOption filetype=blah "somecommand"

The “global” there is the “scope” of the hook. “global” means the hook is present for every buffer, you could also say “buffer” (the hook is present for a single buffer, for every window it’s displayed in) or “window” (the hook is present for a single buffer in a single window).

Instead of having “map”, “nmap”, “imap”, etc. Kakoune’s “map” command takes a mode argument; instead of having “map” and “noremap” all of Kakoune’s maps behave like Vim’s “noremap”. So the translation of “nnoremap key keys” is:

map global normal key keys

The translation of the commands to run will be something like:

: w<ret>: nop %sh{ javac %val{buffile} && java "$(basename "$kak_buffile" .java)" }<ret>

To explain:

  • :w is just like Vim, of course, but note the space between : and w, which prevents this command from polluting your prompt history (when you press <up> at the prompt).
  • Kakoune doesn’t have a ! command to directly execute a shell command, but the %sh{} construct expands to the standard output of running a command (like $() in shell), and the nop command ignores all its arguments.
  • As you can see, Kakoune doesn’t use % to mean “the current buffer file” but the %val{} syntax which expands to various useful bits of Kakoune state. The same information is available in shell expansions via the $kak_* environment variables. See :help expansions for more.

So the snippet to paste into your kakrc would be something like:

hook global WinSetOption filetype=java %{
    map window normal <c-@> %{: w<ret>: nop %sh{ javac %val{buffile} && java "$(basename "$kak_buffile" .java)" }<ret>}
}

…except I can’t actually trigger a mapping with <c-@>, or <c-space>, or <c-^> or anything like that. I can type <c-^> on the command line with the <c-v> prefix (just like Vim) and I can type it in the document, but I can’t make <c-space> do anything at all. Quite possibly nobody’s tried to map it before; I can’t even find an issue for it. I guess I’ll file one.

EDIT: Filed #2553.

2 Likes
hook global WinSetOption filetype=tex %{
        map window normal <c-l> %{: w<ret>: nop %sh{xelatex -interaction batchmode -shell-escape %val{buffile} } }
 }

Following what you said, I changed my kakrc to add the above lines and noting happened. Note just to experiment, I decided to use <c-l> instead of <c-a>.

For better or for worse, the filetype for *.tex files is latex, not tex. Try using the pattern filetype=latex.

This can be easily accomplished by having the following on the init file

 map global normal <c-x> ':w<ret> $ latex $kak_buffile' 

c-x is available and If other options from latex are needed then customize