Lumesh写的lf文件管理器配置
shebang 只是为了语法高亮
ifs 设置,需配合LUME_IFS_MODES设置。更好的解决方案是不直接使用包含多个变量的$fx作为命令参数,而是使用$fx.lines()分割后作为参数。
shellopts -s 表示严格模式。非严格模式允许直接使用字面量作为变量,严格模式可以获得更快的解析速度。
shell 后面指定lume或lumesh作为脚本解析器。
1set ifs "\n"
2set shellopts '-s'
3set shell lumesh
4set filesep "\n"
5& if $LF_LEVEL.to_int() > 1 { lf -remote `send $id echoerr "Nest Level $LF_LEVEL"` }
6& if !Fs.exists('/tmp/lf') {mkdir /tmp/lf}
7& if !Fs.exists('/tmp/lf/files') {touch /tmp/lf/files /tmp/lf/tags /tmp/lf/history; 'copy' >! /tmp/lf/files}
8
9set borderfmt "\033[32m"
10set errorfmt "\033[1;43;41m"
11set timefmt '2006-1-2 15:04'
12set rulerfmt "%{lf_user_wheel}| %a| %p| %{lf_selmode} \033[7;31m %m \033[0m| \033[7;33m %c \033[0m| \033[7;35m %s \033[0m| \033[7;34m %f \033[0m| %i/%t"
13set locale 'zh-CN'
14set tempmarks '=>+@^#'
15
16set drawbox
17set roundbox
18set showbinds
19
20set scrolloff 10
21set icons
22set incsearch
23set incfilter
24set ignorecase
25set anchorfind false
26set findlen 0
27set tabstop 4
28set info 'size'
29set preview
30set sixel
31set previewer ~/.config/lf/previewer
32set dircounts
33set selmode 'dir'
34set user_wheel ''
35map d
36map y
37map p
38map m
39map f
40map c
41map r
42map t
43map G
44map F
45map w
46cmd profile ${{
47 print lf -remote `send $id source ~/.config/lf/profiles/${$argv[0]}`
48}}
49map z2 profile extra
50map z3 profile disk
51map z4 profile convert
52map z5 profile develop
53map z6 profile auto-redraw
54map z7 profile tarzip
55
56cmd open % eprint 'not dir'
57map e $$lf_user_wheel hx $f
58
59
60map zm set info perm
61map zu set info user:group
62
63
64map W $lume
65map . :read; cmd-history-prev;
66map <a-\;> push :<space>$fx<home>
67map <a-4> push $<space>$fx<home>
68map <a-7> push &<space>$fx<home>
69map <a-5> push %<space>$fx<home>
70map <a-1> push !<space>$fx<home>
71
72cmd all-cmd ${{
73 let cmd = lf -remote `query $id cmds` | .lines() | .drop(1) | \
74 .map(x -> {x.split("\t\t") | .first()}) | Ui.pick "select cmd:"
75 lf -remote `send $id :$cmd`
76}}
77map <c-e> all-cmd
78
79cmd history-cmd ${{
80 let cmd = lf -remote `query $id history` | .lines() | Ui.pick "history command:" | .split("\t\t") | .last()
81 lf -remote `send $id $cmd`
82}}
83map <backspace> history-cmd
84map <backspace2> history-cmd
85
86cmd history-dir ${{
87 let hist = lf -remote `query $id jumps` | Into.table('jump','path') | .drop(1) | Ui.pick "choose history:"
88 lf --remote `send $id cd ${$hist.path}`
89}}
90map <c-g> history-dir
91
92cmd quit-print ${{ print $fx ; lf -remote `send $id quit` }}
93map <c-o> quit-print
94
95map <f-12> ${{ lf -remote `query $id maps` | less }}
96
97cmd edit-config ${{
98 hx ~/.config/lf/lfrc
99 lf -remote `send $id source ~/.config/lf/lfrc`
100}}
101map zc edit-config
102
103cmd toggle-preview %{{
104 match $lf_preview {
105 'true' => lf -remote `send $id :set nopreview; set ratios 1:5`
106 _ => lf -remote `send $id :set preview; set ratios 1:2:3`
107 }
108}}
109map zp toggle-preview
110
111cmd toggle-selmode %{{
112 match $lf_selmode {
113 dir => lf -remote `send $id :set selmode 'all'`
114 _ => lf -remote `send $id :set selmode 'dir'`
115 }
116}}
117map zS toggle-selmode
118
119cmd parent-panel-off ${{
120 lf -remote `send $id :set preview; set ratios 2:3`
121}}
122map zP parent-panel-off
123
124cmd toggle-super ${{
125 if $lf_user_wheel {
126 lf -remote `send $id :set user_wheel;set borderfmt \033[32m; set promptfmt '\033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m'`
127 }else{
128 lf -remote `send $id :set user_wheel pkexec;set borderfmt \033[31m; set promptfmt '\033[5;5mSUPER\033[0m $id \033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m'`
129 }
130}}
131map zz toggle-super
132
133map <c-s> source ~/.config/lf/lfrc
134
135map <tab> half-down
136map <backtab> half-up
137map J push 3j
138map K push 3k
139map <c-j> push 7j
140map <c-k> push 7k
141map <a-j> push 10j
142map <a-k> push 10k
143map g<space> push :cd<space>
144map g/ cd /
145map gr cd /
146map gn cd /run
147map go cd /opt
148map gu cd /usr
149map gm cd /mnt
150map gt cd /tmp
151map gp cd /proc
152map ge cd /etc
153map gv cd /var
154map gs cd /usr/share
155map gc cd ~/.config
156map gd cd ~/Documents
157map gD cd ~/Downloads
158map gl cd ~/.local
159map gb cd ~/.local/bin
160map g. cd ~/.config/lf
161map ga cd /usr/share/applications
162map gG bottom
163
164cmd zox %{{
165 if len($argv) {
166 let select=zoxide query --exclude (pwd()) $argv
167 lf -remote `send $id cd $select`
168 }
169}}
170map ; push :zox<space>
171map gz push :zox<space>
172
173cmd zoxide-query ${{
174 let select=zoxide query -i
175 lf -remote `send $id cd $select`
176}}
177map gq zoxide-query
178
179cmd cd-usermedia &{{
180 lf -remote `send $id cd $XDG_RUNTIME_DIR/media`
181}}
182map gi cd-usermedia
183
184cmd follow-link %{{
185 let real=readlink $f
186 lf -remote `send $id select $real`
187}}
188map gL follow-link
189
190cmd select-files &{{
191 let htag= $lf_hidden ? '-H' : ''
192 let r=fd --exact-depth 1 $argv $htag -c never -j 4 | .lines() | .join(' ')
193 lf -remote `send $id :unselect; toggle $r`
194}}
195map Sf select-files -t file
196map Sd select-files -t directory
197map SF select-files -t empty -t file
198map SD select-files -t empty -t dir
199map Sl select-files -t symlink
200map Sx select-files -t executable
201map Sn select-files --regex '^[^.]+$'
202map Se push :select-files<space>-e<space>
203map SE push :select-files<space>--exclude<space>
204map Ss push :select-files<space>--size<space> # -1k +3m
205map Si push :select-files<space>--changed-within<space> # 1min 2h 3d 4week
206map Sb push :select-files<space>--changed-before<space> # 1min 2h 3d 4week
207map So select-files -o root
208
209map Sr push :select-files<space>--regex<space>
210
211map , find
212map <lt> find-prev
213map <gt> find-next
214
215cmd fzf-edit $ hx (fzf)
216map fe fzf-edit
217
218cmd fzf-file ${{
219 let ext = len($argv) ? '-e'+$argv[0] : ''
220 let selected = fd --type 'file' $ext '-S-50k' -j 4 | fzf --preview "~/.config/lf/previewer {} 30 18"
221 lf -remote `send $id select $selected`
222}}
223map ff<space> push :fzf-file<space>
224map fft fzf-file txt
225map ffg fzf-file gz
226map ffm fzf-file md
227map ffs fzf-file sh
228map ffy fzf-file py
229
230cmd fzf-folder ${{
231 select = $lf_user_wheel fd --type d '.' -d 5 -j 4 | fzf --preview 'ls {}'
232 lf -remote `send $id cd $select`
233}}
234map fd fzf-folder
235
236cmd fzf-content ${{
237 let file_type = len($argv)>0 ? $argv[0] : 'sh'
238 let RG_PREFIX = `$lf_user_wheel rg --type $file_type --column --line-number --no-heading --color=always --smart-case --max-filesize 50K`
239 let res = fzf --ansi --disabled \
240 --bind `start:reload:$RG_PREFIX {q}` \
241 --bind `change:reload:sleep 0.1; $RG_PREFIX {q} || true` \
242 --bind "alt-enter:unbind(change,alt-enter)+change-prompt(2. fzf> )+enable-search+clear-query" \
243 --color "hl:-1:underline,hl+:-1:underline:reverse" \
244 --prompt '1. ripgrep> ' \
245 --delimiter ':' \
246 --preview 'bat --color=always {1} --highlight-line {2}' \
247 --header `Searching Content in FileType: $file_type` \
248 if $res {
249 let a = $res.split(':').take(3).join(':')
250 $lf_user_wheel hx $a
251 }
252}}
253map fc<space> push :fzf-content<space>
254map fct fzf-content txt
255map fcm fzf-content md
256map fcs fzf-content sh
257map fcy fzf-content py
258map fcj fzf-content js
259
260
261map \\ filter
262map F<space> filter
263map Ft setfilter .txt
264map Fp setfilter .png
265map Fj setfilter .jpg
266map Fa setfilter .mp3
267map Fv setfilter .mp4
268map Fw setfilter .docx
269map Fx setfilter .xlsx
270map Fg setfilter .gz
271map Fz setfilter .zip
272map Fm setfilter .md
273map Fs setfilter .sh
274map Fy setfilter .py
275map Fc setfilter
276
277
278
279map yy copy
280
281cmd yank-path &{{
282 $fx.lines().join("\n") | wl-copy
283}}
284map yp yank-path
285
286cmd yank-name &{{
287 $fx.lines() | .map(Fs.base_name) | .join("\n") | wl-copy
288}}
289map yn yank-name
290
291cmd yank-basename &{{
292 $fx.lines() | .map(x -> {Fs.base_name(True,$x) | .first()}) | .join("\n") | wl-copy
293}}
294map yb yank-basename
295
296cmd yank-clear &{{
297 '' >! ~/.local/share/lf/files
298 lf -remote 'send clear'
299}}
300map yu yank-clear
301
302cmd yank-list $$fx | hx
303map \| yank-list
304
305map yc cut
306
307cmd delete ${{
308 println '=====DELETE====='.red().bold() $fx '================'.red()
309 if Ui.confirm('Delete these files [y/n]:'){
310 $lf_user_wheel rm -rf $fx.lines()
311 }
312}}
313map dD delete
314
315cmd trash %{{
316 let files = $fx.lines() | List.map(Fs.base_name)
317 let ans = read `Trash: $files [y/N]`
318
319 if $ans == 'y' {
320 mkdir -p /tmp/.trash
321 $lf_user_wheel mv -- $fx.lines() /tmp/.trash/
322 print 'Trash complete!'
323 }else{
324 echo 'Canceled!'
325 }
326}}
327map dd trash
328
329
330cmd mpaste %{{
331 let load=Fs.read ~/.local/share/lf/files | .lines()
332 let files = $load.drop(1)
333 let file_count = len($files)
334 if $file_count==0 {
335 print 'No files yanked'
336 exit 0
337 }
338 let mode=$load.at(0)
339 let base_names = $files.map(Fs.base_name)
340 let ans = read `$mode $file_count files? [y/N]`
341 if $ans == 'y' {
342 match $mode {
343 copy => {
344 $lf_user_wheel cp -r $argv -- $files '.'
345 let tg='='
346 }
347 move => {
348 $lf_user_wheel mv -- $files '.'
349 let tg='>'
350 }
351 }
352
353 '' >! ~/.local/share/lf/files
354 lf -remote 'send clear'
355 for file in $base_names {
356 lf -remote `send $id :select "$file"; tag $tg`
357 }
358 }
359}}
360map po mpaste --backup=numbered --force
361map pb mpaste --backup=numbered
362map pO mpaste --force
363map pi mpaste -i
364map pn mpaste -n
365map pu mpaste --update
366map pP mpaste --update --preserve
367map ps mpaste --symbolic-link
368map pl mpaste --link
369map pH mpaste -H
370map pp paste
371
372
373cmd link %{{
374 let load= Fs.read ~/.local/share/lf/files | .lines()
375 let files=$load.drop(1)
376 let file_count = len($files)
377 if $file_count==0 {
378 print 'No files yanked'
379 exit 0
380 }
381 let mode=$load.at(0)
382 let base_names = $files.map(Fs.base_name)
383
384 for filex in $base_names{
385 if (Fs.exists Fs.join('.',$filex)) {
386 eprint $filex 'Already exists!'
387 exit 1
388 }
389 }
390 match $mode {
391 copy => $lf_user_wheel ln -s -- $files '.'
392 move => $lf_user_wheel ln -- $files '.'
393 }
394
395 '' >! ~/.local/share/lf/files
396 lf -remote 'send clear'
397 for file in $base_names {
398 lf -remote `send $id :select "$file"; tag '@'`
399 }
400
401}}
402map pL link
403
404cmd paste-rsync %{{
405 let load= Fs.read ~/.local/share/lf/files | .lines()
406 let mode=$load.at(0)
407 let files=$load.drop(1)
408 match $mode{
409 copy => {
410 $lf_user_wheel rsync -ar --ignore-existing --info=progress2 -- $files '.'
411 }
412 move => {
413 $lf_user_wheel rsync -ar --remove-source-files --ignore-existing --info=progress2 -- $files '.'
414 }
415 }
416
417 '' >! ~/.local/share/lf/files
418}}
419map pr paste-rsync
420
421cmd paste-to %{{
422 let dest = $argv[0] ?: {print 'Cancelled';exit 0}
423 $lf_user_wheel cp -r --backup=numbered -i -- $fx $dest
424 if Fs.is_dir($dest){
425 let base_names = $fx.lines() | .map(Fs.base_name) | .join("\n")
426 lf -remote `send $id :unselect; cd $dest; select $base_names`
427 }else{
428 lf -remote `send $id :unselect; select $dest; `
429 }
430}}
431map pt push :paste-to<space>
432
433cmd paste-from %{{
434 let dest = $argv[0] ?: {print 'Cancelled';exit 0}
435 $lf_user_wheel cp -r --backup=numbered -i -- $dest '.'
436 let base_name = Fs.base_name($dest)
437 lf -remote `send $id :unselect; select $base_name; `
438}}
439map pf push :paste-from<space>
440
441
442cmd rename-to %{{
443 let base_name = Fs.base_name($fx)
444 let new_name =read `rename "$base_name" to:`
445 if $new_name {
446 $lf_user_wheel mv -- $base_name $new_name
447 lf -remote `send $id :select $new_name`
448 }
449}}
450map mv rename-to
451
452map ch :rename; cmd-home #rename head
453map ct :rename; cmd-end #rename tail
454map ca rename #rename after basename
455map cn :rename; cmd-delete-home #rename basename
456map ce push ca<c-f><c-k> #rename extension
457map cf :rename; cmd-end; cmd-delete-home #rename fullname
458
459cmd bulk-rename ${{
460 let new=mktemp
461 $fs + "\n" >! $new
462 helix $new
463 let old_files = $fs.lines()
464 let new_files = Fs.read $new | .lines()
465 lf -remote `send $id unselect`
466 for pair in List.zip($old_files,$new_files){
467 if $pair[0] != $pair[1]{
468 $lf_user_wheel mv -- $pair[0] $pair[1]
469 lf -remote `send $id select ${$pair[1]}`
470 }
471 }
472 rm $new
473}}
474
475map cb bulk-rename
476
477cmd chmod ${{
478 let ans = read "Mode Bits:"
479 if $ans {
480 $fx |> $lf_user_wheel chmod $ans _
481 lf -remote 'send reload'
482 }
483}}
484map cm chmod
485
486cmd chown %{{
487 let ans = read "new Owner:Group :"
488 if $ans {
489 $fx |> $lf_user_wheel chown $argv $ans -- _
490 lf -remote 'send reload'
491 }
492}}
493map co chown
494map cO chown -R
495
496cmd mkfile %{{
497 if len($argv)>0 {
498 $lf_user_wheel touch -- $argv
499 for file in $argv{
500 lf -remote `send $id select $file; tag '+'`
501 }
502 }
503}}
504map mf push :mkfile<space>
505
506cmd mkdirs ${{
507 if $argv {
508 $lf_user_wheel mkdir -p -- $argv
509 let name = ""
510 for file in $argv{
511 if !$file.starts_with('/'){
512 name = Fs.base_name($file)
513 lf -remote `send $id :select $name; tag '+'`
514 }
515 }
516 }
517}}
518map mk push :mkdirs<space>
519
520cmd folder-selected %{{
521 let dest = read "Fold to :"
522 if $dest {
523 if Fs.exists($dest){
524 eprint 'Dest already Exists'
525 exit 0
526 }
527 $lf_user_wheel mkdir -- $dest
528 let files = $fx | .lines()
529 $lf_user_wheel mv -- $files $dest
530 lf -remote `send $id select '$dest'`
531 }
532}}
533map ms folder-selected
534
535
536map i ${{let LESSOPEN=' | ~/.config/lf/previewer %s 20 30'; less -R -k ~/.config/lf/less.lesskey $f}}
537
538map En &geany $fx
539map Ec &code $fx
540map Ep &lapce $fx
541map Eg &geany $fx
542map Ee &gedit $fx
543map Ea &apostrophe $fx
544map El &lite-xl $fx
545map Em &marker $fx
546map Er &retext $fx
547map Ev &vi $fx
548map Ez &zed $fx
549
550map rr &$lf_user_wheel foot lf '.'
551map rt &thunar '.'
552map rs &spacefm -t '.'
553map rh &hx '.'
554map rc &code '.'
555map rp &lapce '.'
556map rn &geany '.'
557map rl &lite-xl '.'
558map rz &zed '.'
559cmd cmus-play &{{
560 pgrep -x cmus ?: foot cmus
561 cmus-remote -c -q $fx
562 cmus-remote -p -q
563}}
564map Om cmus-play
565cmd open-handlr $ handlr open $fx; lf -remote `send $id unselect`
566map o open-handlr
567
568cmd open-with-gui &$argv[0] $fx ## opens with a gui application outside lf client
569map Og push :open-with-gui<space> ## input application
570
571cmd open-with-cli $$argv[0] $fx ## opens with a cli application inside lf client
572map Oc push :open-with-cli<space> ## input application
573
574map Ox &xarchiver $f
575
576cmd extract-to %{{
577 let dest = $argv[0] ?: {print 'Cancelled'; exit 0}
578 if (Regex.match '\.([gb7xs]z|t[gbx]z|zip|zst|bz2|lz4|lzma|tar|rar|br)$' $f) {
579 let base_name = Fs.base_name(True,$f).first()
580 let npath = Fs.join($dest,$base_name)
581 $lf_user_wheel ouch -q decompress --dir $npath $f
582 lf -remote `send $id :cd $dest; select $base_name; tag '^'`
583 }else{
584 print 'Unsupported file extention'
585 }
586}}
587map ah push :extract-to<space>.<enter>
588map ax push :extract-to<space>/tmp/
589map aX push :extract-to<space>
590
591cmd compress-to ${{
592 let dest = $argv[0] ?: {print 'Cancelled'; exit 0}
593 let sources = $fx.lines()
594 if $dest.ends_with('/'){
595 let base_name = Fs.base_name($sources.first())
596 let dest_file = Fs.join($dest, $base_name)
597 }else{
598 let base_name = Fs.base_name($dest)
599 let dest_file = $dest
600 }
601 if !(Regex.match '\.(gz|tgz|zip|tar|7z|bz|bz2|xz|lzma|sz|lz4|zst|rar)$' $base_name) {
602 base_name = $base_name + '.tgz'
603 dest_file = $dest_file + '.tgz'
604 }
605 $lf_user_wheel ouch compress -qSg $sources $dest_file
606 let dir = Fs.dir_name($dest)
607 lf -remote `send $id :cd $dir; select $base_name; tag '#'`
608}}
609map ac push :compress-to<space>/tmp/
610
611cmd archive-mount ${{
612 let base_name = Fs.base_name($f)
613 let mntdir=`/tmp/lf/mount/$base_name`
614 mkdir -p $mntdir
615 $lf_user_wheel archivemount $f $mntdir -o nosave
616 lf -remote `send $id cd $mntdir`
617}}
618map am archive-mount
619
620map mb mark-save
621
622cmd diff !{{
623 let files = $fs.lines()
624 if len($files)>1 {
625 $lf_user_wheel diff -w $files[0] $files[1] ?: 'Diff'
626 println '-----Finished-----'
627 }else{
628 echo 'please select 2 files!'
629 }
630}}
631map df diff
632
633cmd delta !{{
634 let files = $fs.lines()
635 if len($files)>1 {
636 $lf_user_wheel delta $files[0] $files[1] ?: 'Diff'
637 println '-----Finished-----'
638 }else{
639 echo 'please select 2 files!'
640 }
641}}
642map dt delta
643
644cmd diff-md5 %{{
645 let files = $fs.lines()
646 if len($files)>1 {
647 let lines = $lf_user_wheel md5sum $files[0] $files[1] | .lines()
648 let s1 = $lines[0] | .words() | .at(0)
649 let s2 = $lines[1] | .words() | .at(0)
650 print $s1==$s2 ? 'Same' : 'Differ'
651 }else{
652 echo 'please select 2 files!'
653 }
654}}
655map dm diff-md5
656
657cmd check-sum %{{
658 let ext_name = Fs.base_name(True, $fx).last()
659 match $ext_name {
660 sha512 => sha512sum -c $fx
661 sha384 => sha384sum -c $fx
662 sha256 => sha256sum -c $fx
663 sha224 => sha224sum -c $fx
664 sha1 => sha1sum -c $fx
665 md5 => md5sum -c $fx
666 _ => shasum $fx
667 }
668}}
669map dc check-sum
670
671map d<space> !dust
672
673
674
675cmd mount-dev ${{
676 let sel = lsblk -rno 'name,type,size,mountpoint,label,fstype' | Into.table([name,'type',size,mountpoint,label,fstype]) \
677 | where($type!='disk' && !$mountpoint && $fstype !~: 'member') \
678 | Ui.pick "which to mount:" ?: { print 'no device'; exit 0 }
679
680 if $sel {
681 if !$lf_user_wheel {
682 eprint 'Must be root to mount'
683 exit 1
684 }
685 let src = $sel.type == 'part' ? `/dev/${$sel.name}` : `/dev/mapper/${$sel.name}`
686 let point = $sel.label==None ? $sel.name : $sel.label
687 let dest = `$XDG_RUNTIME_DIR/media/$point`
688 if !Fs.exists($dest){ mkdir -p $dest }
689 $lf_user_wheel mount -m -o 'defaults,noatime' $src $dest ?: \
690 e -> {notify-send 'Mount Failed' $e.msg.lines().join(';'); exit 1}
691 lf -remote `send $id cd $dist`
692 notify-send 'Mount' `device $src mounted`
693 }
694}}
695map mm mount-dev
696
697cmd umount-dev ${{
698 let sel = lsblk -rno 'name,type,size,mountpoint,label,fstype' | Into.table([name,'type',size,mountpoint,label,fstype]) \
699 | where(mountpoint != None) \
700 | Ui.pick() ?.
701
702 if sel {
703 if $PWD ~: $sel.mountpoint {
704 lf -remote `send $id cd /tmp`
705 }
706 $lf_user_wheel umount $sel.mountpoint ?: \
707 e -> {notify-send 'Umount Failed:' $e.msg.lines().join(';'); exit 1}
708 lf -remote `send $id reload`
709 notify-send 'Umount' `device ${sel.name} umounted`
710 }
711}}
712map mu umount-dev
713
714map T tag-toggle
715
716cmd drag-in %{{
717 dest=dragon-drop --target -x -p
718 cp $dest .
719 let base_name = Fs.base_name($dest)
720 lf -remote `send $id :select ${base_name}; tag =`
721}}
722map di drag-in
723
724cmd drag-out &dragon-drop $fx
725map do drag-out
726
727cmd on-cd &{{
728 Sys.print_tty `\033]0;lf $PWD\007`
729}}
730
731on-cd