Skip to content
This repository was archived by the owner on Jun 16, 2024. It is now read-only.
/ exvoker Public archive

A CLI tool. Extract regexes from stdout (e.g. URLs) and invoke commands on them (e.g. open the webpage).

License

Notifications You must be signed in to change notification settings

patrick-kidger/exvoker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Archived: this was a fun project, but these days I make this happen by composing individual commands instead. E.g. I have this script bound to a key in tmux:

#!/usr/bin/env fish

set file (mktemp)
set mode (tmux display-message -p "#{pane_mode}")
if test $mode = "copy-mode"
    set start (math -1 x (tmux display-message -p "#{scroll_position}"))
    set offset (tmux display-message -p "#{pane_height}")
    # An additional offset of 1 is necessary, probably to remove the border at the top.
    set end (math $start + $offset - 1)
    tmux capture-pane -pJ -S $start -E $end > $file
else
    tmux capture-pane -pJ > $file
end
tmux new-window -n "<extract>" "cat $file | rg -o '(http|https)://\\S+[\\S&&[^\'\"]]' | sort | uniq | sk | vipe | <some command here>; rm $file"

exvoker

Extract a regex, invoke a command on it.

The canonical use (that I wrote this for) is to extract URLs from stdout on the command line, and then automatically copy them to clipboard or open them in a web browser.

Installation

cargo install --locked --git https://github.com/patrick-kidger/exvoker

You'll also need to create a ~/.config/exvoker/exvoker.toml file specifying what regexes to extract, and what command to run on them. For example, here's mine:

extract = '''(http|https)://\S+'''
invoke = 'tmux set-buffer -w'

This extracts most URLs, and copies the selected item to my tmux clipboard.
(This URL-matching is deliberately simplistic, and you can try other more complicated regexes if you want to.)

Usage

exvoker reads from stdin and parses out items that match the regex. Using the URL regex above, then this:

echo "https://github.com foo bar http://google.com qux https://twitter.com" | exvoker

produces:

  ▓
❯ https://github.com
  http://google.com
  https://twitter.com

This menu can be navigated (keys listed below), and also has a fuzzy search prompt on the first line:

  go▓
❯ http://google.com
  https://github.com

Once you're happy with your choice, then press Space to select the item, which will run your invoke command on it. (Passed as $invoke $selection.)
Alternatively, press Enter to edit the item before invoking a command on it.

Commands

  • Esc/Control-C: quit (and do nothing)
  • Up/Shift-Tab: move selection up
  • Down/Tab: move selection down
  • Home/End/Left/Right/letters/numbers/punctuation/etc.: edit fuzzy selection
  • Space: select item
  • Enter: select item and edit it (using the same interface as fuzzy selection). Then press either Space or Enter again to select the edited version.

tmux integration

I have bind e run tmux-exvoker in my tmux configuration file, and the executable file tmux-evoker on my $PATH (make sure it's executable: chmod +x tmux-exvoker), with contents:

#!/usr/bin/env fish
set file (mktemp -p /dev/shm)
tmux capture-pane -pJ > $file
tmux new-window -n "<exvoker>" "cat $file | exvoker"

(you may need to adapt this if you use other shells, e.g. bash or zsh)

This will call exvoker on the currently-visible contents of your pane, when you press <prefix> e.

Examples

Open a web browser

To open the selected link in a web browser, include this in exvoker.toml:

invoke = 'xdg-open'

Copy to the system clipboard

Depends exactly what is meant by "system" clipboard, but on many Linux distros that frequently means using the X clipboard:

invoke = 'xsel -ib'

Copy to both the tmux clipboard and the system clipboard

In exvoker.toml:

invoke = 'tmux set-buffer -w'

Automatically rewrite some matches

In this example, we additionally match strings of the form Index <number>, and rewrite them to https://example.org/index/<number>, and then invoke our final command.

In exvoker.toml:

extract = '''((http|https)://\S+|Index [0-9]+)'''
invoke = 'exvoker-invoke'

And in an file exvoker-invoke somewhere on your $PATH (make sure it's executable: chmod +x exvoker-invoke):

#!/usr/bin/env fish
if test (count $argv) -ne 1
    echo "Can only invoke with a single argment"
    exit 1
end
set --function arg $argv[1]
if test (string match --regex '^Index [0-9]+' "$arg")
    set --function arg (string replace 'Index ' 'https://example.org/index/' "$arg")
end
tmux set-buffer -w $arg  # Or whatever else your final command is

The above uses the fish shell, but you could construct something equivalent if you're a bash/zsh/etc. user.

Inspiration

The basic functionality of copying URLs from stdout to clipboard was inspired by the venerable urlview. This is intended as a personal replacement for that. I didn't really like urlview enough (or any of its derivatives), mostly because they involved too many keypresses. For example extracting a URL via urlview involves three keypresses, to select item -> edit item -> close menu. In contrast exvoker only requires a single keypress to select an item.

The command line interface is adapted from dialoguer, which honestly does most of the heavy lifting here.

About

A CLI tool. Extract regexes from stdout (e.g. URLs) and invoke commands on them (e.g. open the webpage).

Topics

Resources

License

Stars

Watchers

Forks

Languages