Nnn integration

Hi!

I’ve been trying to integrate Kakoune with nnn the last little bit, to try to achieve something similar to vim + vim-vinegar + netrw. In other words, I would like to hit - to enter nnn in the parent directory for the active buffer, select a file using nnn, and have it put me back into kakoune with the current buffer set to the selected file from nnn, and close nnn. Preferably I would like this to all happen in the same window.

I believe this is possible using nnn -p -, which from here I gather will use nnn as a selector and output the results to stdout. I’ve seen other people on this forum asking how to achieve something similar, and have been directed to look into connect.kak. I’ve looked into this, and have figured out how to open it in another window (currently kitty, I’m also in the middle of configuring :terminal to open a new i3 window), but it does not close after having selected a file and seems to be leveraging a workflow around VISUAL=edit and setting up the edit command to open a file in the current kakoune session. I understand how useful/powerful that can be in a lot of contexts, but it seems like it shouldn’t be necessary for this because nnn already provides a way to output a file to stdout, and I would like to run this all in the current window.

I think my unix-fu is just lacking (long time linux user - long time bash avoider), I’d really appreciate if someone more skilled in this area could provide some guidance.

Thanks in advance!!

Have you had a look at this wiki page? https://github.com/mawww/kakoune/wiki/Integrating-Other-CLI-apps

It shows how to „suspend and resume“ kakoune and has an example with ranger. Ranger opens in the same window as a selector and closes again, going back to kakoune where a buffer opens with the selected file.

1 Like

I knew I’d seen this before somewhere, thanks! I think I saw that wiki page shortly after I started using Kakoune, but had mostly forgotten about it and it wasn’t showing up in any of my searches. Really appreciate it, I’ll give that a shot tonight!

I will add this functionality to connect.kak, but I need a bit more time.

3 Likes

@alexherbo2 that is awesome, I use a bit of a hack (open tmux pane, then send-keys to maximize it) – works well enough but having a baked in solution would be awesome.

1 Like

Usage

$ kak-connect
:t nnn

EDIT

I want to keep connect.kak code simple, so feedback about the implementation are welcome.

Not that I’m criticizing the code there, but is that the simplest means of using CLI apps? I’m curious.

In this case, I wish It were simple to have kakoune create a split of nnn, and then nnn could just pass the select to the currently running kakoune session instead of opening a new kakoune session as a split in the terminal.

Unless of course kak -c can take a PID, and you can chain that with -e.
So kak -c kak_client_pid -e 'edit $nnn_selection' or something like that.

Maybe it is possible now that I’m thing about it…

Hi parasrah,
I also use and enjoy nnn for its directory pinning. Something else to consider is using it with tmux as this allows the use of both the kak (left pane) and nnn (right pane). While in nnn (right pane) I issue the e command which opens the file in kak (left pane). Issuing the tmux commands C-b z and C-b l to switch between kak (left pane) and nnn (right pane) provides a nice alternative to continuous open and close of nnn.

where C-b = send prefix
      z   = resize pane -Z (zoom)
      l   = select pane -R (right)
# .bashrc
export EDITOR="kak"
export NNN_USE_EDITOR="$EDITOR"

# https://github.com/robertmeta/kakfiles/blob/master/kakrc#L219
define-command nnn -params .. -file-completion %(connect-horizontal; connect-terminal nnn %arg(@)) -docstring "Open with nnn"

# or now with connect.kak
:t nnn

A nice alternative is broot which I use for single pane viewing without switching tmux panes.

# Yes Alex and Robert have got you covered on broot as well
define-command broot -params .. -file-completion %(connect-terminal broot %arg(@)) -docstring "Open with broot"

Hope this helps you some, enjoy. Bye :wave:

Thanks everyone for your suggestions! I actually already had a pretty good workflow of keeping an nnn pane up side b side using kak-connect and i3 (I don’t use tmux) that is very similar to that @duncan. It occurred to me that I actually just wanted the appearance of nnn taking up my current window, which is complicated to achieve for real. For options to achieve that for real, I’d recommend taking a look at connect.kak, @alexherbo2 recently added :connect-detach that works really well for those that launch kakoune using kak-connect. They also suggested window swallowing, which after taking a look at looks like exactly what I want. It gives the appearance of consuming the current window, without all the complications of actually doing that. Unfortunately I haven’t really had time to dig into that too much, so in the short term I’ve fallen back to opening up a new kitty tab and leveraging kak-connect using the following command:

    define-command nnn-current -params 0..1 -file-completion -docstring 'Open file with nnn (volatile)' %define-command nnn-current -params 0..1 -file-completion -docstring 'Open file with nnn (volatile)' %{
    set-kitty-tab-terminal-alias
    connect-terminal sh -c %sh{
        printf %s "edit \$(nnn -p - ${@:-$(dirname "$kak_buffile")})"
    }
    set-default-terminal-alias
}

I will probably improve on this solution to avoid the shell expansion, and maybe try to stop it flickering when it returns to the kakoune instance (because it initially shows the buffer it was previously in). Anyone that comes to this thread looking for a similar solution is more than welcome to take a look at my dotfiles to see my solution and how it evolves.

Thanks again for the help everyone

Actually a little bit more work and I’ve got something working for nnn with the kitty-terminal-tab that is actually pretty fast.

define-command nnn-current -params 0..1 -file-completion -docstring 'Open file with nnn (volatile)' %{
    kitty-terminal-tab sh -c %{
        kak_buffile=$1 kak_session=$2 kak_client=$3
        shift 3
        kak_pwd="${@:-$(dirname "${kak_buffile}")}"
        filename=$(nnn -p - "${kak_pwd}")
        kak_cmd="evaluate-commands -client $kak_client edit $filename"
        echo $kak_cmd | kak -p $kak_session
    } -- %val{buffile} %val{session} %val{client} %arg{@}
}

Mind you right now all my kitty commands rely on a single instance of kitty running using kitty --single-instance so it always opens in the currently scoped kitty window/instance as opposed to the one where kak was launched. I am going to try to work around that using the listen_on config for kitty so I can just launch kitty with no arguments again

What exactly does this connect-horizontal do?

I see in Roberts config file he defines connect-horizontal as

define-command connect-horizontal %{
    alias global terminal tmux-terminal-horizontal
}

But what does that do? terminal is alread the alias for tmux-terminal-horizontal.

It is to decide the position of the next split, similarly to i3 split horizontal|vertical. It was discussed in connect.kak#11.

@parasrah I don’t know how well it could apply in your case, but kitty also offers the concept of overlay which is akin to window swallowing. https://sw.kovidgoyal.net/kitty/launch.html?highlight=overlay

3 Likes

Just added support for nnn.

Configuration

require-module connect-nnn

# Explore files with nnn
alias global explore-files nnn
2 Likes

Awesome thanks alex.

This nnn integration really rocks !

How do you open kak from your project root ? I think I got something as kak $(nnn -p -) as entrypoint but it feels inconsistent pressing <Cr> instead of e. I’d like to not poorly use nnn as the edited files will be relative to their last parent directory which sucks.

Or maybe I should just kak then e :thinking:

PS: Ok then just kak . and explore-files will just do the works. Better !