-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlaziercli
executable file
·156 lines (132 loc) · 5.15 KB
/
laziercli
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/perl
# yet another "hmm, what else can I do with fzf" proof-of-concept program!
# someone pointed me to https://github.com/jesseduffield/lazycli and of course
# I had to implement it in fzf :)
# there are a few shortcuts and conveniences taken, but this is just a POC
# so... meh! (For example, the YAML file shamelessly uses fzf notation for
# the keys and the placeholder variables, so I don't have to actually *do*
# anything except compose the fzf command and let it run!)
# ----------------------------------------------------------------------
# the YAML file that I currently have in my ~/.config/lazierclirc is below
# note the two git related sections at the top -- while this will never
# replace a tool like `tig` or the fugitive plugin in vim, it's a good example
# that shows how for some other system where a similar "exploration" tool does
# not already exist, you can whip one up pretty easily using laziercli!
# I'll use the netstat entries to explain "reload" and "append":
#
# let's say you started with "netstat -pnt". Now, if you hit alt-r, it will
# reload (because netstat info may have changed this is like a refresh)
#
# if you hit alt-l, it will *append* "-l" to your *original* command, thus
# running "netstat -pnt -l", and will reload using that
#
# if you hit alt-b (b for "both"), it will reload with a brand new set of
# options
#
# actually, you can reload with *any* command; it does not have to be a
# netstat command, as you can see from the "alt-f" line, where we are now
# loading "lsof"!
#
# and at any time, alt-r will reload the original command you started with
#
# finally, notice the optional " # " (space, #, space) which precedes a
# "description", for cases where you want to show that instead of the actual
# command in the help text/fzf header
=for YAML
git branch:
enter: "lrc git lg --color=always $(echo {} | cut -c3- | cut -f1 -d' ')"
# where git lg is defined in gitconfig as "git log --oneline --graph --format=...", and has colors
git lg:
# the "--graph" means that there *may* be graph characters appearing before the hash; hence the "grep -o"
enter: "git ls -1 $(echo {}|grep -o ' [0-9a-f]\\{7\\} ')"
netstat:
alt-r: "reload"
alt-l: "append -l # rerun, but only for ports being listened to"
alt-b: "reload netstat -plnut"
alt-f: "reload lsof -iTCP -iUDP # not finding what you're looking for? Try lsof!"
ls:
ctrl-d: "echo rm -v {1}"
ctrl-alt-d: "echo rm -vrf {1}"
alt-v: "vim {1}"
alt-m: "md5sum {1}"
alt-b: "b3sum {1}"
ls -al:
ctrl-d: "echo rm -v {9}"
ctrl-alt-d: "echo rm -vrf {9}"
alt-v: "vim {9}"
alt-m: "md5sum {9}"
alt-b: "b3sum {9}"
ps -f:
alt-r: "reload"
alt-t: "kill {2}"
alt-k: "kill -9 {2}"
date:
alt-r: "reload # rerun date"
alt-s: "reload"
=cut
# ----------------------------------------------------------------------
use warnings;
use strict;
use 5.10.0;
use Data::Dumper;
use YAML::XS qw(DumpFile LoadFile);
my $tty=`tty`; chomp $tty;
my $fzfm = $0;
my $RC = "$ENV{HOME}/.config/lazierclirc";
# ----------------------------------------------------------------------
my $rc = LoadFile($RC);
# get the command being executed, which is basically @ARGV
my $cmd = join(" ", @ARGV);
die "no command?" unless $cmd;
# this is probably something like "ls -al /tmp". Our keys are perhaps "ls",
# and "ls -al". We have to match this $cmd to the longest prefix in our keys
# (i.e., "ls -al")
my $key = "NOT FOUND";
for (sort { length($b) <=> length($a) } keys %$rc) {
if (index($cmd, $_) == 0) {
$key = $_;
last;
}
}
die "command not found in '$RC'" if $key eq "NOT FOUND";
# generate the "--header" and the "--bind" options
my $header;
my @binds;
my $val = $rc->{$key};
for my $c (sort keys %$val) {
my $v = $val->{$c};
# optional description; see examples up in the YAML
my $desc = '';
$v =~ s/ +# +(.*)// and $desc = $1;
# handle reload and append
$v eq "reload" and $v .= " $cmd";
$v =~ s/^append // and $v = "reload $cmd $v";
$header .= sprintf "%-12s\t%s\n", $c, ($desc || $v);
$v =~ s/^reload //
? push @binds, "--bind", "$c:reload($v)"
: push @binds, "--bind", "$c:execute(exec > $tty; exec 2>&1; $v; echo -n 'Press enter...'; read)";
}
# now run fzf
$ENV{FZF_DEFAULT_COMMAND} = $cmd;
my @ret = fzf();
# this is where you'd loop if you cared to do more with this. This is also
# where you'd trap things like the key-combo for a "cd", then cd to the
# directory and rerun fzf, etc.
# ----------------------------------------------------------------------
sub fzf {
my @cmd = ("fzf",
"--ansi",
"--expect", "esc",
"--header", $header,
"--preview", "echo {} | grep --color=always -f <(printf \"%s\\n\" `echo {q}`)",
"--preview-window", "down,wrap,25%",
# preview window helps when the line is too long, since fzf won't scroll horizontally (it seems)
# it also highlights the fzf query terms so you can see where they matched
@binds,
);
open(FZF, "-|", @cmd);
@ret = <FZF>;
close FZF;
chomp(@ret);
return @ret;
}