Command wildcard expansion?

hello there,

Is it possible to do things like that ?

:e **/document*repo*.rb

Should I use %sh{some find command} instead ? What is your convenient way to do that ?

Using connect.kak with the suggested configuration:

  1. Control + t or Control + n to open a terminal connected to the client.
:connect-terminal
  1. In your terminal, edit or simply e to open files in the client.
$ edit app/controllers/*.rb

Yeah, I am using connect.kak but generally a limited feature scope.

But I feels having to open an external terminal just to wildcard a filename is a little bit too much. Plus, if I write system configurations as with sudo, having a fast, simple and flexible way to query subdirectory files is necessary.

Plus: I’d relly like to have a vanilla, no additional resources at all, way to open files fast. Honestly the good filename auto completion is almost good enough.

If you are OK with globbing that is provided by sh (i.e. no recursive globs **), you could use a simple sh expansion to call edit multiple times:

define-command prompt-edit %{
    prompt -file-completion "edit-all:" %{
    	evaluate-commands %sh{
        	eval set -- "$kak_quoted_text"
        	for f; do
        	    printf 'edit "%s"\n' "$f"
    	    done
        }
    }
}
map global user e ': prompt-edit<ret>'

@ReedWade Without scripting:

  1. Open a scratch buffer
  2. Pipe to find
  3. Select each line
  4. Press gf

A put command can be a good companion to your find.

~/.local/bin/put

#!/bin/sh

printf '%s\n' "$@"

Selecting multiple lines and using gf never works for me, it just opens the last one.

@ReedWade If you do not want a terminal, you can use the connect-shell command or its alias T.

Example

:T e *.rb

@robertmeta Alt + s

Thanks a lot for all replies.

I pretty like the scratch + pipe find solution as it allow powerful pipes to filter results plus all the Kakoune selection ones.

I was thinking, does a default find module similar to the grep one could interest anyone ?

Not sure if I can change the alias to $ but it could be very nice.

@occivink has a file tree extension.

I have this custom gf mapping, which opens all selected buffers, and goes to the one in the main selection.

def -hidden open-selected-files %{
    eval -itersel %{ try %{ exec -with-hooks -draft gf } }
    exec -with-hooks gf
}
map -docstring "file" global goto f "<esc>: open-selected-files<ret>"
2 Likes

Shouldn’t be the default behavior?

1 Like

I think it should, yes

I’ve done a grep like find module. It works but still wip for the moment

https://paste.sr.ht/~reedwade/b931d4fbbb4b1c5ba2d06c34cc064d8042998bbe

I’m still trying to understand what is done in the grep line 59 :thinking:

It’s pretty much exactly as the comment above line 59 describes.

For :grep-next-match to work, it needs to know which is the current match, stored in the hidden grep_current_line option. This is set by :grep-jump, either as part of a command like :grep-next-match or by the user hitting <ret> on a grep result. Let’s say grep_current_line is 10, then `:grep-next-match needs to:

  • execute 10g to move the selection to beginning of that line
  • execute (say) gl to move the cursor to the end of that line, past the grep result
  • search for the next line of output that looks like a result
  • call :grep-jump to open that match in the main client

The straightforward way to do that would be something like:

exec "%opt{grep_current_line}g gl /^[^:]+:\d+:<ret>"
grep-jump

Unfortunately, this all falls apart if :grep-next-match is called before :grep-jump: grep_current_line defaults to zero, so the exec command results in:

  • 0 prefix is ignored
  • gg moves the cursor to the first line of the buffer
  • l moves the cursor forward by one character
  • the search winds up always finding the second match

Trick #1 is replacing the gl command with <a-l>. If grep_current_line is set, this extra key behaves exactly the same as gl, so that functionality is intact. If grep_current_line is not set, this is a key that is not present in the goto menu, so the menu is dismissed without moving the selection and the search proceeds as intended.

Trick #2 is adding ge to the beginning of the exec command. If grep_current_line is set, ge has no effect because the selection will immediately be moved back to where it needs to be. If grep_current_line is not set, 0g<a-l> will not move the selection, so ge ensures it will be at the end of the file — the search command is thus guaranteed to wrap around and always find the first match.

Adding these two tricks together, we get the code in grep.kak:

exec "ge %opt{grep_current_line}g<a-l> /^[^:]+:\d+:<ret>"
grep-jump
1 Like

Wooha thanks a lot for those explanations !

With that in mind, here the find.kak module

ps: It completely solve my initial issue as I now can

:find app/ -name document*repo*.rb

But it isn’t, and I am glad I am not insane. :slight_smile: