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