A new kitten to easily search files and open the results at the matched line by clicking on them.
This commit is contained in:
parent
8021686154
commit
083c47b0f0
@ -14,6 +14,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
|||||||
- Add support for easily editing or downloading files over SSH sessions
|
- Add support for easily editing or downloading files over SSH sessions
|
||||||
without the need for any special software, see :doc:`kittens/remote_file`
|
without the need for any special software, see :doc:`kittens/remote_file`
|
||||||
|
|
||||||
|
- A new :doc:`kittens/hyperlinked_grep` kitten to easily search files and open
|
||||||
|
the results at the matched line by clicking on them.
|
||||||
|
|
||||||
- Improve rendering of borders when using minimal borders. Use less space and
|
- Improve rendering of borders when using minimal borders. Use less space and
|
||||||
do not display a box around active windows
|
do not display a box around active windows
|
||||||
|
|
||||||
|
|||||||
43
docs/kittens/hyperlinked_grep.rst
Normal file
43
docs/kittens/hyperlinked_grep.rst
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
Hyperlinked grep
|
||||||
|
=================
|
||||||
|
|
||||||
|
This kitten allows you to search your files using `ripgrep
|
||||||
|
<https://www.google.com/search?q=ripgrep>`_ and open the results
|
||||||
|
directly in your favorite editor in the terminal, at the line containing
|
||||||
|
the search result, simply by clicking on the result you want.
|
||||||
|
|
||||||
|
To set it up, first create :file:`~/.config/kitty/open-actions.conf` with the
|
||||||
|
following contents:
|
||||||
|
|
||||||
|
.. code:: conf
|
||||||
|
|
||||||
|
# Open any file with a fragment in the editor, fragments are generated
|
||||||
|
# by the hyperlink_grep kitten and nothing else so far.
|
||||||
|
protocol file
|
||||||
|
has_fragment yes
|
||||||
|
action launch --type=overlay vim +$FRAGMENT $FILE_PATH
|
||||||
|
|
||||||
|
# Open text files without fragments in the editor
|
||||||
|
protocol file
|
||||||
|
mime text/*
|
||||||
|
has_fragment no
|
||||||
|
action launch --type=overlay $EDITOR $FILE_PATH
|
||||||
|
|
||||||
|
|
||||||
|
Now, run a search with::
|
||||||
|
|
||||||
|
kitty +kitten hyperlinked_grep something
|
||||||
|
|
||||||
|
Hold down the :kbd:`ctrl+shift` keys and click on any of the
|
||||||
|
result lines, to open the file in vim at the matching line. If
|
||||||
|
you use some editor other than vim, you should adjust the
|
||||||
|
:file:`open-actions.conf` file accordingly.
|
||||||
|
|
||||||
|
Finally, add an alias to your shell's rc files to invoke the kitten as ``hg``::
|
||||||
|
|
||||||
|
alias kitty +kitten hyperlink_grep
|
||||||
|
|
||||||
|
|
||||||
|
You can now run searches with::
|
||||||
|
|
||||||
|
hg some-search-term
|
||||||
0
kittens/hyperlinked_grep/__init__.py
Normal file
0
kittens/hyperlinked_grep/__init__.py
Normal file
60
kittens/hyperlinked_grep/main.py
Normal file
60
kittens/hyperlinked_grep/main.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from typing import Callable, cast
|
||||||
|
from urllib.parse import quote_from_bytes
|
||||||
|
|
||||||
|
|
||||||
|
def write_hyperlink(write: Callable[[bytes], None], url: bytes, line: bytes, frag: bytes = b'') -> None:
|
||||||
|
write(b'\033]8;;')
|
||||||
|
write(url)
|
||||||
|
if frag:
|
||||||
|
write(b'#')
|
||||||
|
write(frag)
|
||||||
|
write(b'\033\\')
|
||||||
|
write(line)
|
||||||
|
write(b'\033]8;;\033\\')
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
if not sys.stdout.isatty() and '--pretty' not in sys.argv:
|
||||||
|
os.execlp('rg', 'rg', *sys.argv[1:])
|
||||||
|
cmdline = ['rg', '--pretty'] + sys.argv[1:]
|
||||||
|
p = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
|
||||||
|
assert p.stdout is not None
|
||||||
|
write: Callable[[bytes], None] = cast(Callable[[bytes], None], sys.stdout.buffer.write)
|
||||||
|
sgr_pat = re.compile(br'\x1b\[.*?m')
|
||||||
|
osc_pat = re.compile(b'\x1b\\].*?\x1b\\\\')
|
||||||
|
num_pat = re.compile(b'^(\\d+):')
|
||||||
|
|
||||||
|
in_result: bytes = b''
|
||||||
|
hostname = socket.gethostname().encode('utf-8')
|
||||||
|
|
||||||
|
for line in p.stdout:
|
||||||
|
line = osc_pat.sub(b'', line) # remove any existing hyperlinks
|
||||||
|
clean_line = sgr_pat.sub(b'', line).rstrip() # remove SGR formatting
|
||||||
|
if not clean_line:
|
||||||
|
in_result = b''
|
||||||
|
write(b'\n')
|
||||||
|
continue
|
||||||
|
if in_result:
|
||||||
|
m = num_pat.match(clean_line)
|
||||||
|
if m is not None:
|
||||||
|
write_hyperlink(write, in_result, line, frag=m.group(1))
|
||||||
|
else:
|
||||||
|
if line.strip():
|
||||||
|
path = quote_from_bytes(os.path.abspath(clean_line)).encode('utf-8')
|
||||||
|
in_result = b'file://' + hostname + path
|
||||||
|
write_hyperlink(write, in_result, line)
|
||||||
|
else:
|
||||||
|
write(line)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
x
Reference in New Issue
Block a user