How to open and jump to line/col like vim-fetch?

I’m a heavy user of vim-fetch and have been missing this feature in kak. Is there a built-in way to do this? I’d be happy to come up with a plugin if necessary if someone would point me at some docs I could take a look at.

Not familiar with vim-fetch, but you can provide the line and column when opening kakoune like this: kak +12:3 file.txt which will jump to line 12 column 3. Note that the + part has to come before the filename in some contexts, so best to always do so.

Just took a look and that looks like a plug-in I would love to have. For those reading, the desired functionality is to select a string formatted as file:line:column and use gf to go to it.

@mmlb the :edit command does already have support for this which you can see with the clippy hints when you type the command.

@EpocSquadron thanks I’ll take a look at :edit for inspiration. vim-fetch is a very handy little plugin that helps very much.

If you have a tool that outputs file:line:column output, you might want to set the lintcmd or makecmd options to the tool’s command-line (depending on whether it works on the current buffer or arbitrary files in the current directory), and then use :lint or :make to run it - both commands capture the tool output, stick it in a scratch buffer, and add a <ret> mapping which lets you jump straight to the indicated position.

I tend to mostly use it when opening vim. Looking at log lines from other windows for example and I just want to navigate to said line. I also have a wrapper around git grep -n that fixes up the line so its $file.$line. So my needs are really just for when invoking kak.

Ah, yeah, the old copy/paste-from-log-file thing.

It shouldn’t be too hard to write a Kakoune command that accepts a parameter of the form file:line or file:line:column, decodes it, and calls :edit with the appropriate syntax.

You could probably write a very similar shell-script wrapper for the kak binary, but I don’t think there’s a good way to have one implementation for both use-cases.

@Screwtapello thanks for this hint. I’ve finally started working on this and am coming across 2 issues. They may be github issue worthy but wanted to float it here before going to github.

I have the following kakrc:

# kak: set filetype=kak
hook global BufNewFile .*:[0-9]+ %{ evaluate-commands %sh{
  echo BufNewFile filename=$kak_buffile >&2
  #set -x
  #newfile=$(echo "$kak_buffile" | awk -F: '{print $1}')
  #line=$(echo "$kak_buffile" | awk -F: '{print $2}')
  #echo newfile=$newfile >&2;
  #echo line=$line >&2;
  #echo "delete-buffer;";
  #echo "edit $newfile $line";
}}
hook global BufCreate .*:[0-9]+ %{ evaluate-commands %sh{
  echo BufCreate filename=$kak_buffile >&2
  set -x
  newfile=$(echo "$kak_buffile" | awk -F: '{print $1}')
  line=$(echo "$kak_buffile" | awk -F: '{print $2}')
  echo newfile=$newfile >&2;
  echo line=$line >&2;
  echo "delete-buffer;";
  echo "edit $newfile $line";
}}

and when I try opening /tmp/t.t:5 I get 2 behaviors that I’m not sure are correct.

  1. The file /tmp/t.t is correctly opened but the cursor stays at line 1. Once I’m in the buffer I can run :edit /tmp/t.t 5 and kak correctly jumps to line 5. Is what I’m doing correct and kak has a bug maybe?

  2. I never see a buffer named /tmp/t.t:5 which is what I expect, but I do see an error message and the content of *debug* buffer is:

*** This is the debug buffer, where debug info will be written ***
shell stderr: <<<
BufCreate filename=/tmp/t.t:5
++ echo /tmp/t.t:5
++ awk -F: '{print $1}'
+ newfile=/tmp/t.t
++ echo /tmp/t.t:5
++ awk -F: '{print $2}'
+ line=5
+ echo newfile=/tmp/t.t
newfile=/tmp/t.t
+ echo line=5
line=5
+ echo 'delete-buffer;'
+ echo 'edit /tmp/t.t 5'
>>>
shell stderr: <<<
BufNewFile filename=/tmp/t.t:5
>>>
error while opening file '/tmp/t.t:5':
    buffer got removed during its creation

Do you know a way to hi-jack to opening file process w/o getting the “buffer got removed” message?

@mmlb Your approach seems to complex, why not just use wrap the :edit command:

define-command edit-colon -params 1 -file-completion %{
    evaluate-commands %sh{
        echo "edit -existing -- $1" | sed 's/:/ /g'
    }
} -docstring "Like edit but understands file:line:col parameters"
alias global e edit-colon
1 Like

@krobelus has good advice, but to answer your questions more specifically:

In Kakoune, “cursor position” is associated with a window, so that you can have multiple windows displaying the same buffer, with a different cursor position in each. Buf* hooks are executed in buffer context, not window context, so the hook can’t set the cursor position — there’s nowhere to put it until the buffer is displayed in a window. I imagine the process goes something like this:

  1. User edits /tmp/t.t:5, a new buffer is created and displayed in the current window
  2. BufCreate hook runs
    1. The /tmp/t.t:5 buffer is deleted
    2. A new buffer for /tmp/t.t is created
    3. Because there’s no window associated with this context, the line number is ignored
  3. The buffer this window was displaying was deleted, so it switches back to a recently-used buffer, which happens to be the buffer added by the hook. Since this is the first time this buffer has been displayed in any window, the cursor defaults to the first line.

As for the error you see, I imagine the proximate cause is that you have two buffer-related hooks, but the first hook deletes the buffer before the second hook can run. Deleting that second hook (BufNewFile) might clean that up, or it might not - I don’t know if it’s an error for BufCreate to delete the buffer it’s running in. When a new buffer is created, Kakoune always triggers BufCreate, followed by one of BufNewFile or BufOpenFile depending on whether the named file exists on disk.

In your case, unless you follow krobelus’ advice, you’d probably want to hook WinDisplay instead of any of the Buf* hooks, since WinDisplay runs in an actual window context, so you can do things like move the cursor to where you want it to be.

2 Likes

Thanks, but my main use case is from the cli when opening new files. Its only a small minority of the time that I want to do something like gf to the file & line. This edit-colon works in that case, though my preferred form is to integrate with the “default” mechanism, which is also why I’d rather not wrap the kak command in any tool.

Thanks this helped quite a lot. I moved my hook over to WinDisplay and it works great. The cursor is at the intended line and the error message is gone. Now to expand the matching and look into hooking into/overriding gf.

Should we expect a kak-fetch plugin soon? :slight_smile:

Indeed, I’ll add some more formats first though. I’ll get it up before trying to figure out the gf equivalent though. :+1:

I’ve been running on GitHub - mmlb/kak-fetch for about a week now!

1 Like

nice readme you’ve got there :wink:

TODO: An actual README :smiley: