I'd like to request a feature that I've seen in Tilix that has proven to be a big timesaver. Tilix lets one define custom hotlink patterns: patterns that will match text in the terminal and substitute it into a user-defined URL.
For example, I have the following pattern defined:
| Pattern | Command |
|---|---|
| BZ:(\d+) | xdg-open https://bugzilla.redhat.com/$1 |
If there is text in the terminal that looks something like BZ:12345, that becomes an active link that when selected will open the corresponding bug in my browser. Or for working with Launchpad I have:
| Pattern | Command |
|---|---|
| (closes\|partial\|related)-bug: #?(\d+) | xdg-open https://bugs.launchpad.net/bugs/$2 |
These features are great when reading email (in the terminal), browser git log, looking at changelogs and READMEs, etc, because when I see text that looks like:
commit 24fe74d126f23bea56c87524b1005a2aaacb870c
[...]
Should not skip volume_size check for bdm.image_id == image_ref case
The volume size should be checked in bdm.sourece_type=image,
dest_type=volume case no matter what the image
is, but we skipped the check if the bdm.image_id == image_ref,
we should not skipped the volume_size check.
Change-Id: Ib10579280b63a4dd59ac76733aa0ff48fd2e024b
closes-bug: 1818798
I can just select the closes-bug: 1818798 link to open the bug report in the browser.
I dont understand what you are asking for. The hints kitten allows you
to run arbitrary programs with the matched text. Which means you can do
anything you like with the match, including write a script to pste it
into a url and call xdg-open
Rather than closing this, maybe give me a chance to clarify? I'm sorry if I was unclear. I want to be able to define custom patterns that will let me control-shift-click on text that matches a user-defined pattern and have it behave like a URL. I don't think that's possible with the hints kitten, but maybe I am mistaken?
just because something is closed doesn't mean you cant clarify and it can be re-opened if needed. The hints kitten can totally do that except that the hints kitten does not involve any clicking, it is purely keyboard riven
So...the hints kitten totally can't do the thing I'm asking about. I'll take a look at a keyboard based model, but I was really hoping to expand the functionality of the existing URL matching mechanism.
kitty is keyboard focused and you will find that the hints kitten is
both for flexible and faster and more powerful than pretty much any
mouse based approach.
@larsks the URL matching algorithm build into kitty can't easily be changed, it is written in C, there is no regex or anything like that. The hints kitten on the other hand is easily configurable.
@kovidgoyal how difficult would it be to add mouse support to the hints kitten?
So, forget mouse support.
I'd be happy if I could just get the hints version to work, but after looking over the hints documentation I'm not sure it's possible to do what I want. It looks like I would have to have an individual hotkey for each regular expression, which seems like it would quickly grow unmanageable.
For a single regular expression, I can obviously do something like this:
map kitty_mod+x kitten hints --type regex --regex 'Closes-bug: #(\d+)' --program open-lp-bug
But I don't have a single regular expression. I have at least:
| Pattern | Replacement |
|---|---|
| rhbz#(\d+) | xdg-open https://bugzilla.redhat.com/$1 |
| (depends-on\|change-id): (\w+) | xdg-open https://review.opendev.org/#/q/$2 |
| (closes\|partia\lrelated)-bug: #?(\d+) | xdg-open https://bugs.launchpad.net/bugs/$2 |
| BZ: ?#?(\d+) | xdg-open https://bugzilla.redhat.com/$1 |
| LP: ?#?(\d+) | xdg-open https://bugs.launchpad.net/bugs/$1 |
The hints kitten only accepts a single regular expression. I could create a giant frankenexpression that matches all of the above, but since hints only sends a single value to --program there's no away to differentiate between any of the matches.
If there were a way to have the hints kitten execute a chunk of Python code and provide it with the actual regex match object, that would be great. Or if there were a way to pass all match groups to the program, it would be possible to provide sufficient context to figure out what to do...but that would still be really ugly. Being able to provide a table (YAML?) of expression/actions would be much cleaner.
Let me know if I'm missing something.
Dont use groups, match the entire text, pass it to the program and have
the program further process it, extracting the important bits and
calling xdg-open. And regexes have an OR operator, so why
would you need to mass multiple ones?
@Luflosi what would be the point of adding mouse support? why would
anyone first trigger the kitten using a keystroke and then switch to the
mouse to select the individual match when it takes only a single
additional keystroke to select the match?
If you really wanted mouse support, the way to do it would be to have
something like the hint kitten run on ctrl+shift+click or whatever with
the screen of text and the mouse position and have it match and run the
action accordingly. This is never going to work for live highlighting on
mouse over as performance is too poor but it can be done
action-on-click. But its not something I want to do as the hints kitten
works perfectly for me.
And regexes have an OR operator...
...which you'll note I'm already making use of in my examples
...so why would you need to mass multiple ones?
That would be the "create a giant frankenexpression" solution, which I think becomes increasingly less maintainable as you add additional expressions. Also, because of the whole "hints only passes a single value" thing, you have to discard a bunch of regex syntax. E.g., you can't use an expression like this:
(closes|partia\lrelated)-bug: #?(\d+)
Because that will only pass the result of the final (\d+) group, so you lose your context. I even tried nesting everything, i.e.:
((closes|partia\lrelated)-bug: #?(\d+))
I guess maybe you would expand it like:
(closes-bug: #?\d+|partial-bug: #?`\d+|related-bug: #?\d+)
And then taking into account all the examples in my earlier comment you get something like:
(closes-bug: #?\d+|partial-bug: #?`\d+|related-bug: #?\d+|depends-on: \w+|change-id: \w+|rhbz#\d+|BZ: ?#?\d+|LP: ?#?\d+)
...and then of course you have to repeat all the regular expression in the handler program. So now you've got a large, hard to read regular expression and duplicate effort. I don't know, I must be doing a rotten job of explaining myself because this looks terrible to me, but I appreciate that you've got a different perspective. I'll look into forking the hints kitten and seeing if I can put together something more user-friendly for my own use. Thanks for taking some time to discuss this.
On Wed, Oct 30, 2019 at 07:26:54PM -0700, Lars Kellogg-Stedman wrote:
...so why would you need to mass multiple ones?
That would be the "create a giant frankenexpression" solution, which I think becomes increasingly less maintainable as you add additional expressions. Also, because of the whole "hints only passes a single value" thing, you have to discard a bunch of regex syntax. E.g., you can't use an expression like this:
(closes|partia\lrelated)-bug: #?(\d+)Because that will only pass the result of the final
(\d+)group, so you lose your context. I guess maybe you would expand it like:
What? Why? regexes have non-capturing groups, like this:
(?:whatever)
(closes-bug: #?\d+|partial-bug: #?`\d+|related-bug: #?\d+)And then taking into account all the examples in my earlier comment you get something like:
(closes-bug: #?\d+|partial-bug: #?`\d+|related-bug: #?\d+|depends-on: \w+|change-id: \w+|rhbz#\d+|BZ: ?#?\d+|LP: ?#?\d+)...and then of course you have to repeat all the regular expression in the handler program. So now you've got a large, hard to read regular expression and duplicate effort. I don't know, I must be doing a rotten job of explaining myself because this looks terrible to me, but I appreciate that you've got a different perspective. I'll look into forking the
hintskitten and seeing if I can put together something more user-friendly for my own use. Thanks for taking some time to discuss this.
What? use verbose mode for the regex and it will be perfectly readable.
You dont even need to repeat it twice, simply have the script read it
from kitty.conf and replace (?: with (
Oh and if I were you, I would simply modify the builtin hints kitten and not bother with an external script at all. You can write your own kittens https://sw.kovidgoyal.net/kitty/kittens/custom.html
@larsks I know what you are asking for, and I was looking for something similar. It took digging through the source code and some trial and error, but I got something working. I created a file named open_selection.py in ~/.config/kitty with the following text
def main(args):
pass
def handle_result(args, data, target_window_id, boss):
w = boss.window_id_map.get(target_window_id)
if w is not None:
selection = w.text_for_selection()
cwd = w.cwd_of_child
boss.open_url(selection,'xdg-open',cwd=cwd)
handle_result.no_ui = True
Then I added
map f9 kitten open_selection.py
to kitty.conf. Now I can double-click on a filename and press f9 to open it. I write a lot of slideshows in Markdown, so it is nice to be able to open images that are included in the markdown without leaving vim.
It's not the exact same behavior, but I like it better because 1) I don't have to write a regex :), and 2) it doesn't require that the entire screen text be parsed for matches. You just select what you want and press a key. In your case, you could create a map of regex/program pairs to apply to the selection to get close to the behavior you want, and your regex would only have to work on the selected text, instead of the entire screen buffer. I'll probably end up doing something similar with pyparsing. I just got this working tonight.
@CD3 if you just want to perform arbitrary actions on the current
selection with a keypress you dont need to do any of that, just use the
existing pipe functionality: https://sw.kovidgoyal.net/kitty/pipe.html
That way you can pipe the current selection to an arbitrary program on
keypress and do whatever you like with it.
@kovidgoyal Thanks. I didn't realize that. I submitted a pull request (#2110 ) to add that to the documentation.
@kovidgoyal You mentioned that why add mouse support, but there is support in line.c to parse and add linking for existing urls. I think the ask here is just to make that configurable (either via API or via config)
Is there a way via hints or other kittens to add support for underlining certain patters to open to other urls?
The hints kitten supports not only arbitrary regular expressions but
arbitrary python programs to both identify and act on matches.
I agree with @nemith's idea for this - my use case for kitty is to replace the sidebar terminal in VSCode. I'd find that the sidebar terminal would crash if it couldn't handle the input, but kitty is much more consistent. I miss being able to click on filenames in there and have them open in VSCode, and would like to achieve something similar through this issue being completed.
Most helpful comment
So...the hints kitten totally can't do the thing I'm asking about. I'll take a look at a keyboard based model, but I was really hoping to expand the functionality of the existing URL matching mechanism.