jump{,-next,-previous} cmds to navigate any grep-like buffer

`grep-next-match` works only on the `*grep*` buffer so it can't be used
on buffers that were preserved by renaming or on other grep-flavored
buffers created by 3rd party plugins kakoune-find and kakoune-lsp,
like `*find*` and `*references*`.

Let's generalize `grep-next-match` with a `jump-next` command that
takes a buffer argument.

This renames some options but I think they're not commonly used.
kakoune-lsp is an exception that uses grep_current_line but it's no big
deal, things will fail loud and early if options are missing.

Since grep.kak and friends now depend on jump.kak, move the jumpclient
declaration there as well.
This commit is contained in:
Johannes Altmanninger 2024-02-25 11:12:58 +01:00 committed by Maxime Coste
parent 7ebf7cfccf
commit c81266d4f6
5 changed files with 101 additions and 89 deletions

View File

@ -27,7 +27,7 @@ define-command -params ..1 \
evaluate-commands -draft %{ evaluate-commands -draft %{
edit! -fifo ${dir}/fifo -debug *clang-output* edit! -fifo ${dir}/fifo -debug *clang-output*
set-option buffer filetype make set-option buffer filetype make
set-option buffer make_current_error_line 0 set-option buffer jump_current_line 0
hook -once -always buffer BufCloseFifo .* %{ nop %sh{ rm -r ${dir} } } hook -once -always buffer BufCloseFifo .* %{ nop %sh{ rm -r ${dir} } }
}" }"

View File

@ -1,8 +1,7 @@
# require-module jump
declare-option -docstring "shell command run to search for subtext in a file/directory" \ declare-option -docstring "shell command run to search for subtext in a file/directory" \
str grepcmd 'grep -RHn' str grepcmd 'grep -RHn'
declare-option -docstring "name of the client in which utilities display information" \
str toolsclient
declare-option -hidden int grep_current_line 0
define-command -params .. -docstring %{ define-command -params .. -docstring %{
grep [<arguments>]: grep utility wrapper grep [<arguments>]: grep utility wrapper
@ -30,7 +29,7 @@ define-command -params .. -docstring %{
printf %s\\n "evaluate-commands -try-client '$kak_opt_toolsclient' %{ printf %s\\n "evaluate-commands -try-client '$kak_opt_toolsclient' %{
edit! -fifo ${output} *grep* edit! -fifo ${output} *grep*
set-option buffer filetype grep set-option buffer filetype grep
set-option buffer grep_current_line 0 set-option buffer jump_current_line 0
hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } } hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } }
}" }"
}} }}
@ -39,60 +38,23 @@ complete-command grep file
hook -group grep-highlight global WinSetOption filetype=grep %{ hook -group grep-highlight global WinSetOption filetype=grep %{
add-highlighter window/grep group add-highlighter window/grep group
add-highlighter window/grep/ regex "^([^:\n]+):(\d+):(\d+)?" 1:cyan 2:green 3:green add-highlighter window/grep/ regex "^([^:\n]+):(\d+):(\d+)?" 1:cyan 2:green 3:green
add-highlighter window/grep/ line %{%opt{grep_current_line}} default+b add-highlighter window/grep/ line %{%opt{jump_current_line}} default+b
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/grep } hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/grep }
} }
hook global WinSetOption filetype=grep %{ hook global WinSetOption filetype=grep %{
hook buffer -group grep-hooks NormalKey <ret> grep-jump hook buffer -group grep-hooks NormalKey <ret> jump
hook -once -always window WinSetOption filetype=.* %{ remove-hooks buffer grep-hooks } hook -once -always window WinSetOption filetype=.* %{ remove-hooks buffer grep-hooks }
} }
declare-option -docstring "name of the client in which all source code jumps will be executed" \
str jumpclient
define-command -hidden grep-jump %{ define-command -hidden grep-jump %{
evaluate-commands -save-regs a %{ # use evaluate-commands to ensure jumps are collapsed jump
try %{
evaluate-commands -draft %{
execute-keys ',xs^([^:\n]+):(\d+):(\d+)?<ret>'
set-register a %reg{1} %reg{2} %reg{3}
}
set-option buffer grep_current_line %val{cursor_line}
evaluate-commands -try-client %opt{jumpclient} -verbatim -- edit -existing -- %reg{a}
try %{ focus %opt{jumpclient} }
}
}
} }
define-command grep-next-match -docstring 'Jump to the next grep match' %{ define-command grep-next-match -docstring %{alias for "jump-next *grep*"} %{
evaluate-commands -try-client %opt{jumpclient} %{ jump-next *grep*
buffer '*grep*'
# First jump to end of buffer so that if grep_current_line == 0
# 0g<a-l> will be a no-op and we'll jump to the first result.
# Yeah, thats ugly...
execute-keys ge %opt{grep_current_line}g<a-l> /^[^:\n]+:\d+:<ret>
grep-jump
}
try %{
evaluate-commands -client %opt{toolsclient} %{
buffer '*grep*'
execute-keys gg %opt{grep_current_line}g
}
}
} }
define-command grep-previous-match -docstring 'Jump to the previous grep match' %{ define-command grep-previous-match -docstring %{alias for "jump-previous *grep*"} %{
evaluate-commands -try-client %opt{jumpclient} %{ jump-previous *grep*
buffer '*grep*'
# See comment in grep-next-match
execute-keys ge %opt{grep_current_line}g<a-h> <a-/>^[^:\n]+:\d+:<ret>
grep-jump
}
try %{
evaluate-commands -client %opt{toolsclient} %{
buffer '*grep*'
execute-keys gg %opt{grep_current_line}g
}
}
} }

66
rc/tools/jump.kak Normal file
View File

@ -0,0 +1,66 @@
provide-module jump %§§
declare-option -docstring "name of the client in which all source code jumps will be executed" \
str jumpclient
declare-option -docstring "name of the client in which utilities display information" \
str toolsclient
declare-option -hidden int jump_current_line 0
define-command -hidden jump %{
evaluate-commands -save-regs a %{ # use evaluate-commands to ensure jumps are collapsed
try %{
evaluate-commands -draft %{
execute-keys ',xs^([^:\n]+):(\d+):(\d+)?<ret>'
set-register a %reg{1} %reg{2} %reg{3}
}
set-option buffer jump_current_line %val{cursor_line}
evaluate-commands -try-client %opt{jumpclient} -verbatim -- edit -existing -- %reg{a}
try %{ focus %opt{jumpclient} }
}
}
}
define-command jump-next -params 1 -docstring %{
jump-next <bufname>: jump to next location listed in the given *grep*-like location list buffer.
} %{
evaluate-commands -try-client %opt{jumpclient} -save-regs / %{
buffer %arg{1}
jump-select-next
jump
}
try %{
evaluate-commands -client %opt{toolsclient} %{
buffer %arg{1}
execute-keys gg %opt{jump_current_line}g
}
}
}
complete-command jump-next buffer
define-command -hidden jump-select-next %{
# First jump to end of buffer so that if jump_current_line == 0
# 0g<a-l> will be a no-op and we'll jump to the first result.
# Yeah, thats ugly...
execute-keys ge %opt{jump_current_line}g<a-l> /^[^:\n]+:\d+:<ret>
}
define-command jump-previous -params 1 -docstring %{
jump-previous <bufname>: jump to previous location listed in the given *grep*-like location list buffer.
} %{
evaluate-commands -try-client %opt{jumpclient} -save-regs / %{
buffer %arg{1}
jump-select-previous
jump
}
try %{
evaluate-commands -client %opt{toolsclient} %{
buffer %arg{1}
execute-keys gg %opt{jump_current_line}g
}
}
}
complete-command jump-previous buffer
define-command -hidden jump-select-previous %{
# See comment in jump-select-next
execute-keys ge %opt{jump_current_line}g<a-h> <a-/>^[^:\n]+:\d+:<ret>
}

View File

@ -1,3 +1,5 @@
# require-module jump
declare-option \ declare-option \
-docstring %{ -docstring %{
The shell command used by lint-buffer and lint-selections. The shell command used by lint-buffer and lint-selections.
@ -11,14 +13,11 @@ declare-option -hidden line-specs lint_messages
declare-option -hidden int lint_error_count declare-option -hidden int lint_error_count
declare-option -hidden int lint_warning_count declare-option -hidden int lint_warning_count
declare-option -docstring "name of the client in which utilities display information" \
str toolsclient
define-command -hidden -params 1 lint-open-output-buffer %{ define-command -hidden -params 1 lint-open-output-buffer %{
evaluate-commands -try-client %opt{toolsclient} %{ evaluate-commands -try-client %opt{toolsclient} %{
edit! -fifo "%arg{1}/fifo" -debug *lint-output* edit! -fifo "%arg{1}/fifo" -debug *lint-output*
set-option buffer filetype make set-option buffer filetype make
set-option buffer make_current_error_line 0 set-option buffer jump_current_line 0
} }
} }

View File

@ -1,12 +1,11 @@
# require-module jump
declare-option -docstring "shell command run to build the project" \ declare-option -docstring "shell command run to build the project" \
str makecmd make str makecmd make
declare-option -docstring "pattern that describes lines containing information about errors in the output of the `makecmd` command. Capture groups must be: 1: filename 2: line number 3: optional column 4: optional error description" \ declare-option -docstring "pattern that describes lines containing information about errors in the output of the `makecmd` command. Capture groups must be: 1: filename 2: line number 3: optional column 4: optional error description" \
regex make_error_pattern "^([^:\n]+):(\d+):(?:(\d+):)? (?:fatal )?error:([^\n]+)?" regex make_error_pattern "^([^:\n]+):(\d+):(?:(\d+):)? (?:fatal )?error:([^\n]+)?"
declare-option -docstring "name of the client in which utilities display information" \
str toolsclient
declare-option -hidden int make_current_error_line
define-command -params .. \ define-command -params .. \
-docstring %{ -docstring %{
@ -20,7 +19,7 @@ define-command -params .. \
printf %s\\n "evaluate-commands -try-client '$kak_opt_toolsclient' %{ printf %s\\n "evaluate-commands -try-client '$kak_opt_toolsclient' %{
edit! -fifo ${output} -scroll *make* edit! -fifo ${output} -scroll *make*
set-option buffer filetype make set-option buffer filetype make
set-option buffer make_current_error_line 0 set-option buffer jump_current_line 0
hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } } hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } }
}" }"
}} }}
@ -28,7 +27,7 @@ define-command -params .. \
add-highlighter shared/make group add-highlighter shared/make group
add-highlighter shared/make/ regex "^([^:\n]+):(\d+):(?:(\d+):)?\h+(?:((?:fatal )?error)|(warning)|(note)|(required from(?: here)?))?.*?$" 1:cyan 2:green 3:green 4:red 5:yellow 6:blue 7:yellow add-highlighter shared/make/ regex "^([^:\n]+):(\d+):(?:(\d+):)?\h+(?:((?:fatal )?error)|(warning)|(note)|(required from(?: here)?))?.*?$" 1:cyan 2:green 3:green 4:red 5:yellow 6:blue 7:yellow
add-highlighter shared/make/ regex "^\h*(~*(?:(\^)~*)?)$" 1:green 2:cyan+b add-highlighter shared/make/ regex "^\h*(~*(?:(\^)~*)?)$" 1:green 2:cyan+b
add-highlighter shared/make/ line '%opt{make_current_error_line}' default+b add-highlighter shared/make/ line '%opt{jump_current_line}' default+b
hook -group make-highlight global WinSetOption filetype=make %{ hook -group make-highlight global WinSetOption filetype=make %{
add-highlighter window/make ref make add-highlighter window/make ref make
@ -36,13 +35,13 @@ hook -group make-highlight global WinSetOption filetype=make %{
} }
hook global WinSetOption filetype=make %{ hook global WinSetOption filetype=make %{
alias buffer jump make-jump
alias buffer jump-select-next make-select-next
alias buffer jump-select-previous make-select-previous
hook buffer -group make-hooks NormalKey <ret> make-jump hook buffer -group make-hooks NormalKey <ret> make-jump
hook -once -always window WinSetOption filetype=.* %{ remove-hooks buffer make-hooks } hook -once -always window WinSetOption filetype=.* %{ remove-hooks buffer make-hooks }
} }
declare-option -docstring "name of the client in which all source code jumps will be executed" \
str jumpclient
define-command -hidden make-open-error -params 4 %{ define-command -hidden make-open-error -params 4 %{
evaluate-commands -try-client %opt{jumpclient} %{ evaluate-commands -try-client %opt{jumpclient} %{
edit -existing "%arg{1}" %arg{2} %arg{3} edit -existing "%arg{1}" %arg{2} %arg{3}
@ -59,45 +58,31 @@ define-command -hidden make-jump %{
execute-keys gl<a-?> "Entering directory" <ret><a-:> execute-keys gl<a-?> "Entering directory" <ret><a-:>
# Try to parse the error into capture groups, failing on absolute paths # Try to parse the error into capture groups, failing on absolute paths
execute-keys s "Entering directory [`']([^']+)'.*\n([^:\n/][^:\n]*):(\d+):(?:(\d+):)?([^\n]+)\n?\z" <ret>l execute-keys s "Entering directory [`']([^']+)'.*\n([^:\n/][^:\n]*):(\d+):(?:(\d+):)?([^\n]+)\n?\z" <ret>l
set-option buffer make_current_error_line %val{cursor_line} set-option buffer jump_current_line %val{cursor_line}
set-register a "%reg{1}/%reg{2}" "%reg{3}" "%reg{4}" "%reg{5}" set-register a "%reg{1}/%reg{2}" "%reg{3}" "%reg{4}" "%reg{5}"
} catch %{ } catch %{
set-register / %opt{make_error_pattern} set-register / %opt{make_error_pattern}
execute-keys <a-h><a-l> s<ret>l execute-keys <a-h><a-l> s<ret>l
set-option buffer make_current_error_line %val{cursor_line} set-option buffer jump_current_line %val{cursor_line}
set-register a "%reg{1}" "%reg{2}" "%reg{3}" "%reg{4}" set-register a "%reg{1}" "%reg{2}" "%reg{3}" "%reg{4}"
} }
} }
make-open-error %reg{a} make-open-error %reg{a}
} }
} }
define-command -hidden make-select-next %{
define-command make-next-error -docstring 'Jump to the next make error' %{
evaluate-commands -try-client %opt{jumpclient} -save-regs / %{
buffer '*make*'
set-register / %opt{make_error_pattern} set-register / %opt{make_error_pattern}
execute-keys "%opt{make_current_error_line}ggl" "/<ret>" execute-keys "%opt{jump_current_line}ggl" "/<ret>"
make-jump
}
try %{
evaluate-commands -client %opt{toolsclient} %{
buffer '*make*'
execute-keys %opt{make_current_error_line}g
}
} }
define-command -hidden make-select-previous %{
set-register / %opt{make_error_pattern}
execute-keys "%opt{jump_current_line}g" "<a-/><ret>"
} }
define-command make-previous-error -docstring 'Jump to the previous make error' %{ define-command make-next-error -docstring %{alias for "jump-next *make*"} %{
evaluate-commands -try-client %opt{jumpclient} -save-regs / %{ jump-next *make*
buffer '*make*'
set-register / %opt{make_error_pattern}
execute-keys "%opt{make_current_error_line}g" "<a-/><ret>"
make-jump
}
try %{
evaluate-commands -client %opt{toolsclient} %{
buffer '*make*'
execute-keys %opt{make_current_error_line}g
}
} }
define-command make-previous-error -docstring %{alias for "jump-previous *make*"} %{
jump-previous *make*
} }