Lf harmadik felvonás

enlightened Ez az oldal a közösségért készül. heart Kövess minket máshol is:  Linux Mint Magyar Közösség a Mastodon-on  Telegram csatorna – csak hírek  Beszélgessünk a Telegram – Linux csevegő csoport  Hírek olvasása RSS segítségével  Linux Mint Hivatalos Magyar Közösség a Facebook-on      Linux Mint Baráti Kör a Facebook-on
wink Ha hasznosnak találod, és szeretnéd, hogy folytatódjon, támogasd a munkát Ko-fi vagy Paypal segítségével. laugh

Hát kérem az imádott lf fájlkezelő lett az első versenyző, aki megérte a harmadik felvonást, nagy taps! Ilyen az, mikor a fafaragónak az égig érő fát adod oda, amit aztán farigcsálhat élete végéig...!
No, ezután a kissé elérzékenyülős bevezető után, nézzük mi változott!

- Először is óriási munkába kezdtem, az összes terminálos fájlkezelőnél, amiket használok (lf, vifm, yazi, stb,) igyekszem egységesíteni a kezelést, természetesen az lf is átesett egy ilyen kúrán, és ehhez kapcsolódóan a konfiguráció teljes strukturális átszervezésen esett át, ami szerintem sokkal átláthatóbb.
- Kitty terminálon visszakerült a teljes értékű képelőnézet (könnyen átszabható a protokolt támogató egyéb terminálokra), természetesen a chafa és a timg is megmaradt menekülő útnak.
- Bekerült egy megnyitás adott programmal opció, 'O' aztán pötyögjük a program nevét.
- Szintén új funkció, hogy lekérhetjük a kijelölt fájlok/könyvtárak lemezen foglalt méretét, és összegzést is kérhetünk erről (u/U).
- Bekerült egy könyvtárfa nézet funkció is.
- A vágólap már működik automatikusan X11 és Wayland környezetben is (természetesen a segédprogramokat telepíteni kell, ahogy a többi funkcióhoz is).
- A végleges törléskor biztonsági kérdést kapunk.
- Link létrehozása konkrét névvel.
- Korábban a .-kezdetű (rejtett) fájlok a vim-ben nyíltak meg, akkor is, ha pl. esetleg képfájl volt, ezt most már ellenőrizzük.
- Több apró hiba javításra került (pl. fzf integráció még mindig döcögött, remélhetőleg most már jó)... 

Nézzük a konkrét konfigurációs állományokat!

~/.config/lf/lfrc:

# =========================
# ALAP BEÁLLÍTÁSOK
# =========================

set shell sh
set shellopts '-eu'
set hidden true
set number true
set cursorpreviewfmt "\033[7m"
set icons true
set drawbox true
set ignorecase true
set smartcase true
set incsearch true
set preview true
set info size:time
set ratios 1:2:3
set mouse true
set previewer ~/.config/lf/preview
set cleaner ~/.config/lf/cleaner

set scrolloff 3
set period 1
set incfilter true
set wrapscan true
set anchorfind true
set findlen 0

# =========================
# BILLENTYŰPARANCSOK
# =========================
#
#  q, Q         kilépés
#  <enter>      megnyitás (alapértelmezett program)
#  o            megnyitás (alapértelmezett program)
#  O            megnyitás adott programmal
#  <f-3>        megnyitás most programmal
#  <f-4>        megnyitás vim-ben
#  c            kijelölések törlése
#  a            kijelölések megfordítása
#
#  y            másolás (lf vágólap)
#  d            kukába helyezés (trash-put)
#  x            kivágás (lf vágólap)
#  p, <f-9>     beillesztés (lf vágólap)
#  P            felülírás / felülírás kérdés nélkül
#  Y            útvonal másolása rendszer vágólapra
#
#  <space>      kijelölés + léptetés le
#  <f-5>        másolás (lf vágólap)
#  <f-6>        kivágás (lf vágólap)
#  <f-7>        új könyvtár létrehozása
#  <f-8>, D     végleges törlés (rákérdezés)
#  <delete>     végleges törlés (rákérdezés)
#  <f-2>, r     átnevezés
#  R            tömeges átnevezés
#  E            archívum kibontása
#  Z            zip archívum létrehozása
#  L            szimbolikus link létrehozása
#  T            könyvtárfa (tree -L 2)
#
#  gh           ugrás ~ (home)
#  gp           ugrás ~/Pontfájlok/
#  gc           ugrás ~/.config/
#  gd           ugrás ~/Dokumentumok
#  gD           ugrás ~/Letöltések
#  g/           ugrás /
#  g-           ugrás az előző könyvtárba
#
#  <c-u>        fél oldal fel
#  <c-d>        fél oldal le
#  .            rejtett fájlok mutatása / elrejtése
#  zf           szűrő (filter) — csak az egyező fájlokat mutatja
#  zp           előnézet ki/be
#  u            méretret a lemezen
#  U            fájlok teljes mérete
#
#  sn           rendezés: név szerint
#  ss           rendezés: méret szerint
#  st           rendezés: idő szerint
#
#  F            fzf kereső
#  C            lfrc újratöltése

map q quit
map Q quit
map <enter> open
map o open
map O openwith
map <f-3> $most "$f"
map <f-4> $vim "$f"
map c unselect
map a invert

map y copy
map d trash
map x cut
map p paste
map <f-9> paste
map P overwrite
map Y clip

map <space> toggle;down
map <f-5> copy
map <f-6> cut
map <f-7> push %mkdir<space>
map <f-8> delete-confirm
map D delete-confirm
map <delete> delete-confirm
map <f-2> rename
map r rename
map R bulkrename
map E extract
map Z zip
map L link
map T tree

map gh cd ~
map gp cd ~/Pontfájlok/
map gc cd ~/.config/
map gd cd ~/Dokumentumok
map gD cd ~/Letöltések
map g/ cd /
map g- cd -

map <c-u> half-up
map <c-d> half-down
map . set hidden!
map zf filter
map zp set preview!
map u du
map U dus

map sn set sortby natural
map ss set sortby size
map st set sortby time

map F fzf
map C source ~/.config/lf/lfrc

# =========================
# PARANCSOK
# =========================

# --- megnyitás ---

cmd open ${{ 
    mime="$(file --mime-type -Lb -- "$f")"

    case "$(basename "$f")" in
        *.md)
            if command -v apostrophe >/dev/null 2>&1; then
                apostrophe "$f" >/dev/null 2>&1 &
            else
                "${EDITOR:-vim}" "$f"
            fi
            ;;

        *.png|*.jpg|*.jpeg|*.gif|*.webp)
            if command -v imv-dir >/dev/null 2>&1; then
                imv-dir "$f" >/dev/null 2>&1 &
            elif command -v imv >/dev/null 2>&1; then
                imv "$f" >/dev/null 2>&1 &
            else
                xdg-open "$f" >/dev/null 2>&1 &
            fi
            ;;

        *.mp4|*.mkv|*.webm|*.avi|*.mp3|*.flac|*.ogg)
            if command -v mpv >/dev/null 2>&1; then
                mpv "$f" >/dev/null 2>&1 &
            else
                xdg-open "$f" >/dev/null 2>&1 &
            fi
            ;;

        *.pdf)
            if command -v zathura >/dev/null 2>&1; then
                zathura "$f" >/dev/null 2>&1 &
            else
                xdg-open "$f" >/dev/null 2>&1 &
            fi
            ;;

        *.html)
            xdg-open "$f" >/dev/null 2>&1 &
            ;;

        .*)
            case "$mime" in
                text/*|*/xml|application/json)
                    "${EDITOR:-vim}" "$f"
                    ;;
                *)
                    xdg-open "$f" >/dev/null 2>&1 &
                    ;;
            esac
            ;;

        *)
            case "$mime" in
                text/*|*/xml|application/json)
                    "${EDITOR:-vim}" "$f"
                    ;;
                *)
                    xdg-open "$f" >/dev/null 2>&1 &
                    ;;
            esac
            ;;
    esac
}}

cmd openwith ${{ 
    printf "Program neve: "
    read prog
    [ -n "$prog" ] || exit 1
    nohup $prog "$f" >/dev/null 2>&1 &
}}

# --- fájlműveletek ---

cmd trash ${{ 
    if command -v trash-put >/dev/null 2>&1; then
        trash-put "$fx"
    else
        printf '%s\n' "A trash-put nem érhető el."
    fi
}}

cmd delete-confirm ${{ 
    printf "Végleges törlés — biztos? (i/n) "
    read ans
    [ "$ans" = "i" ] || exit 0
    printf '%s\n' "$fx" | while IFS= read -r f; do
        [ -n "$f" ] && rm -r -- "$f"
    done
    lf -remote "send $id reload"
}}

cmd overwrite ${{ 
    filelist="$HOME/.local/share/lf/files"
    [ -f "$filelist" ] || exit 1

    mode="$(head -n 1 "$filelist" 2>/dev/null || true)"
    tail -n +2 "$filelist" 2>/dev/null | while IFS= read -r file; do
        [ -n "$file" ] || continue
        case "$mode" in
            copy) rsync -a -- "$file" ./ ;;
            move) rsync -a --remove-source-files -- "$file" ./ ;;
        esac
    done

    lf -remote "send $id load"
    lf -remote "send $id echo done"
}}

# --- átnevezés ---

cmd bulkrename ${{ 
    old="$(mktemp)"
    new="$(mktemp)"

    if [ -n "$fs" ]; then
        printf '%s\n' "$fs" | while IFS= read -r f; do
            basename "$f"
        done > "$old"
    else
        find . -maxdepth 1 -mindepth 1 -printf '%P\n' 2>/dev/null > "$old" || ls -A1 > "$old"
    fi

    cp "$old" "$new"
    "${EDITOR:-vim}" "$new"

    [ "$(wc -l < "$old")" -ne "$(wc -l < "$new")" ] && {
        rm -f "$old" "$new"
        exit 1
    }

    paste "$old" "$new" |
    while IFS="$(printf '\t')" read -r src dst; do
        [ "$src" = "$dst" ] && continue
        [ -e "$dst" ] && continue
        mv -- "$src" "$dst"
    done

    rm -f "$old" "$new"
    lf -remote "send $id reload"
}}

# --- archívumok ---

cmd extract ${{ 
    case "$f" in
        *.tar.bz2) tar xjf "$f" ;;
        *.tar.gz) tar xzf "$f" ;;
        *.tar.xz) tar xJf "$f" ;;
        *.tar.zst) tar --zstd -xf "$f" ;;
        *.bz2) bunzip2 "$f" ;;
        *.rar) unar "$f" ;;
        *.gz) gunzip "$f" ;;
        *.tar) tar xf "$f" ;;
        *.tbz2) tar xjf "$f" ;;
        *.tgz) tar xzf "$f" ;;
        *.zip) unzip "$f" ;;
        *.7z) 7z x "$f" ;;
        *) printf '%s\n' "Nem támogatott archívum: $f" ;;
    esac
}}

cmd zip ${{ 
    printf "Archívum neve: "
    read ans
    [ -n "$ans" ] || exit 1
    printf '%s\n' "$fx" | zip -r "$ans.zip" -@
}}

# --- keresés ---

cmd fzf ${{ 
    file="$(
        if command -v fd >/dev/null 2>&1; then
            fd --hidden --exclude .git . 2>/dev/null
        elif command -v fdfind >/dev/null 2>&1; then
            fdfind --hidden --exclude .git . 2>/dev/null
        else
            find . -path '*/.git' -prune -o -print 2>/dev/null
        fi |
        fzf --preview '
            if [ -d {} ]; then
                if command -v eza >/dev/null 2>&1; then
                    eza -la --group-directories-first -- {}
                else
                    ls -la -- {}
                fi
            else
                if command -v bat >/dev/null 2>&1; then
                    bat --color=always --style=numbers,changes --line-range :200 -- {}
                elif command -v batcat >/dev/null 2>&1; then
                    batcat --color=always --style=numbers,changes --line-range :200 -- {}
                else
                    sed -n "1,200p" -- {}
                fi
            fi
        '
    )"

    if [ -n "$file" ]; then
        lf -remote "send $id cd \"$(dirname "$file")\""
        lf -remote "send $id select \"$(basename "$file")\""
    fi
}}

# --- egyéb ---

cmd clip ${{ 
    if command -v wl-copy >/dev/null 2>&1; then
        printf '%s\n' "$fx" | wl-copy
    elif command -v xclip >/dev/null 2>&1; then
        printf '%s\n' "$fx" | xclip -selection clipboard
    elif command -v xsel >/dev/null 2>&1; then
        printf '%s\n' "$fx" | xsel --clipboard --input
    else
        printf '%s\n' "Nincs clipboard eszköz (wl-copy/xclip/xsel)."
    fi
}}

# $ prefix: kilép az lf-ből, lefuttatja a parancsot, visszalép
# less-sel a kimenet addig látható, amíg q-val ki nem lépsz
# $fx = újsorokkal elválasztott kijelölt fájlok; végén awk számolja az összesítést
cmd du $printf '%s\n' "$fx" | while IFS= read -r file; do du -sh -- "$file"; done | less
cmd du $printf '%s\n' "$fx" | while IFS= read -r file; do du -sh -- "$file"; done; echo; echo "=== ÖSSZESEN ==="; printf '%s\n' "$fx" | while IFS= read -r file; do du -sk -- "$file"; done | awk '{s+=$1} END {if(s>=1048576) printf "%.2fG\n", s/1048576; else if(s>=1024) printf "%.2fM\n", s/1024; else printf "%dK\n", s}' | less

# könyvtárfa: ha könyvtáron állunk, azt mutatja; ha fájlon, a szülőkönyvtárat
cmd tree $tree -L 2 -- "$(if [ -d "$f" ]; then printf '%s' "$f"; else dirname "$f"; fi)" | less

# szimbolikus link: megkérdezi a nevet, az aktuális könyvtárban hozza létre
cmd link ${{ 
    printf "Link neve: "
    read name
    [ -n "$name" ] || exit 1
    ln -s -- "$f" "$name"
    lf -remote "send $id reload"
}} 

~/.config/lf/preview:

#!/bin/sh
set -eu

file="${1:-}"
w="${2:-80}"
h="${3:-24}"
x="${4:-0}"
y="${5:-0}"

[ -n "$file" ] || exit 1
[ -e "$file" ] || exit 1

mime="$(file --mime-type -Lb -- "$file" 2>/dev/null || printf '%s' application/octet-stream)"
cache="${XDG_CACHE_HOME:-$HOME/.cache}/lf-preview"
mkdir -p -- "$cache"
find "$cache" -type f -mtime +30 -delete 2>/dev/null || true

have() { command -v "$1" >/dev/null 2>&1; }

hash_of() {
    if have sha256sum; then
        printf '%s' "$1" | sha256sum | awk '{print $1}'
    elif have md5sum; then
        printf '%s' "$1" | md5sum | awk '{print $1}'
    else
        printf '%s' "$1" | cksum | awk '{print $1}'
    fi
}

preview_image() {
    if [ -n "${KITTY_WINDOW_ID:-}" ] && have kitty; then
        kitty +kitten icat --silent --stdin no --transfer-mode file \
            --place "${w}x${h}@${x}x${y}" -- "$1" </dev/null >/dev/tty
        exit 1
    elif have timg; then
        timg -g "${w}x${h}" -- "$1"
    elif have chafa; then
        chafa --format symbols --symbols block+border --fill block --size "${w}x${h}" -- "$1"
    else
        file -- "$1"
    fi
}

preview_text() {
    if have bat; then
        bat --color=always --style=numbers,changes --line-range :250 --paging=never -- "$1"
    elif have batcat; then
        batcat --color=always --style=numbers,changes --line-range :250 --paging=never -- "$1"
    else
        sed -n '1,250p' -- "$1"
    fi
}

preview_meta() {
    if have exiftool; then
        exiftool -a -G1 -- "$1" 2>/dev/null | sed -n '1,120p'
    else
        file -- "$1"
    fi
}

case "$mime" in
    image/*)
        preview_image "$file"
        ;;

    video/*)
        thumb="$cache/$(hash_of "$file").jpg"
        if [ ! -f "$thumb" ] && have ffmpegthumbnailer; then
            ffmpegthumbnailer -i "$file" -o "$thumb" -s 0 >/dev/null 2>&1 || true
        fi
        [ -f "$thumb" ] && preview_image "$thumb" || preview_meta "$file"
        ;;

    audio/*)
        preview_meta "$file"
        ;;

    application/pdf)
        if have pdftotext; then
            pdftotext -l 8 -- "$file" - 2>/dev/null | {
                if have bat; then
                    bat --language=txt --style=plain --color=always --paging=never
                elif have batcat; then
                    batcat --language=txt --style=plain --color=always --paging=never
                else
                    cat
                fi
            }
        else
            preview_meta "$file"
        fi
        ;;

    text/*|application/json|application/xml|*/xml|inode/x-empty)
        preview_text "$file"
        ;;

    application/zip|application/x-tar|application/gzip|application/x-bzip2|application/x-7z-compressed)
        if have bsdtar; then
            bsdtar -tf -- "$file" | sed -n '1,200p'
        elif have tar; then
            case "$mime" in
                application/x-tar) tar -tf -- "$file" | sed -n '1,200p' ;;
                application/gzip) tar -tzf -- "$file" | sed -n '1,200p' ;;
                application/x-bzip2) tar -tjf -- "$file" | sed -n '1,200p' ;;
                *) file -- "$file" ;;
            esac
        elif have unzip && [ "${file##*.}" = "zip" ]; then
            unzip -l -- "$file" | sed -n '1,200p'
        else
            file -- "$file"
        fi
        ;;

    inode/directory)
        if have eza; then
            eza -la --group-directories-first -- "$file" | sed -n '1,200p'
        else
            ls -la -- "$file"
        fi
        ;;

    *)
        preview_meta "$file"
        ;;
esac

~/.config/lf/cleaner:

#!/bin/sh
if [ -n "${KITTY_WINDOW_ID:-}" ] && command -v kitty >/dev/null 2>&1; then
    kitty +kitten icat --clear --stdin no --silent --transfer-mode file </dev/null >/dev/tty
elif command -v timg >/dev/null 2>&1; then
    timg --clear
fi

Nincsenek jó híreim, még mindig akadnak ötleteim, szal lehet még foglak a témával kínozni benneteket!

Előző felvonás: https://linuxmint.hu/blog/2026/05/lf-masodik-felvonas

Berus