A new kitten to easily search files and open the results at the matched line by clicking on them.

This commit is contained in:
Kovid Goyal 2020-09-18 19:33:51 +05:30
parent 8021686154
commit 083c47b0f0
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 106 additions and 0 deletions

View File

@ -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

View 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

View File

View 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()