# _______        __________
# __  __ \_________  /___(_)____________________
# _  / / /__  __ \  __/_  /_  __ \_  __ \_  ___/
# / /_/ /__  /_/ / /_ _  / / /_/ /  / / /(__  )
# \____/ _  .___/\__/ /_/  \____//_/ /_//____/
#        /_/
# Shell
set shell sh
set shellopts '-eu'
set ifs "\n"

# Interface
set ratios '1:2'
set dircounts
set hidden
set info 'size'
set icons
set preview
set previewer '~/.local/bin/scope.sh 2>/dev/null'

# General
set globsearch
set incsearch
set ignorecase
set tabstop 4
# set filesep ' '

# _________                                         _________
# __  ____/____________ __________ _________ _____________  /_______
# _  /    _  __ \_  __ `__ \_  __ `__ \  __ `/_  __ \  __  /__  ___/
# / /___  / /_/ /  / / / / /  / / / / / /_/ /_  / / / /_/ / _(__  )
# \____/  \____//_/ /_/ /_//_/ /_/ /_/\__,_/ /_/ /_/\__,_/  /____/
#
# define a custom 'open' command
# This command is called when current file is not a directory. You may want to
# use either file extensions and/or mime types here
cmd open ${{
    case $(file --mime-type $f -b) in
        text/* | */xml) $EDITOR $fx;;
        audio/*) ffplay -nodisp -autoexit $fx;;
        video/*) mpv $fx;;
        *) for f in $fx; do setsid $OPENER $f > /dev/null 2> /dev/null & done;;
    esac
}}

cmd open-with %{{
   printf "Open with: " 
   read ans

   for file in "$fx"
   do
       $ans $file >/dev/null 2>&1 &
   done
   
   lf -remote 'send reload'
}}

# extract the current file with the right command
# (xkcd link: https://xkcd.com/1168/)
cmd extract ${{
    set -f
    case $f in
        *.tar.bz|*.tar.bz2|*.tbz|*.tbz2) tar xjvf $f;;
        *.tar.gz|*.tgz) tar xzvf $f;;
        *.tar.xz|*.txz) tar xJvf $f;;
        *.zip) unzip $f;;
        *.rar) unrar x $f;;
        *.7z) 7z x $f;;
    esac
}}
cmd atool %atool -xD "$f"

# compress current file or selected files with tar and gunzip
cmd tar ${{
    set -f
    mkdir $1
    cp -r $fx $1
    tar czf $1.tar.gz $1
    rm -rf $1
}}

# compress current file or selected files with zip
cmd zip ${{
    set -f
    mkdir $1
    cp -r $fx $1
    zip -r $1.zip $1
    rm -rf $1
}}

# fzf
cmd fzf_jump ${{
    res="$(find . -maxdepth 1 | fzf --no-multi --reverse --header='Jump to location')"
    if [ -f "$res" ]; then
    cmd="select"
    elif [ -d "$res" ]; then
    cmd="cd"                                                       
    fi
    lf -remote "send $id $cmd \"$res\""
}}

# selection
cmd select-files ${{
    { echo "$fs"; find -L "$(pwd)" -mindepth 1 -maxdepth 1 -type f; } |
        if [ "$lf_hidden" = "false" ]; then
          # remove any hidden files so you only select files you can see.
          grep -v '/\.[^/]\+$'
        else
          cat
        fi |
        sed '/^$/d' | sort | uniq -u |
        xargs -d '\n' -r -I{} lf -remote "send $id toggle {}"
}}
cmd select-dirs ${{
    { echo "$fs"; find -L "$(pwd)" -mindepth 1 -maxdepth 1 -type d; } |
        if [ "$lf_hidden" = "false" ]; then
          grep -v '/\.[^/]\+$'
        else
          cat
        fi |
        sed '/^$/d' | sort | uniq -u |
        xargs -d '\n' -r -I{} lf -remote "send $id toggle {}"
}}

# cp, mv with progression
cmd paste &{{
    load=$(lf -remote 'load')
    mode=$(echo "$load" | sed -n '1p')
    list=$(echo "$load" | sed '1d')
    if [ $mode = 'copy' ]; then
        rsync -av --ignore-existing --progress $list . \
        | stdbuf -i0 -o0 -e0 tr '\r' '\n' \
        | while read line; do
            lf -remote "send $id echo $line"
        done
    elif [ $mode = 'move' ]; then
        mv -n $list .
    fi
    lf -remote 'send load'
    lf -remote 'send clear'
}}

# basic stuff
cmd mkdir %mkdir "$@"
cmd touch %touch "$@"
cmd chmod %{{
  printf "Mode Bits: "
  read ans

  for file in "$fx"
  do
    chmod $ans $file
  done

  lf -remote 'send reload'
}}

# bulk rename
cmd bulk-rename ${{
    old=$(mktemp)
    new=$(mktemp)
    [ -n $fs ] && fs=$(ls)
    printf "$fs\n" > $old
    printf "$fs\n" > $new
    $EDITOR $new
    [ $(cat $new | wc -l) -ne $(cat $old | wc -l) ] && exit
    paste $old $new | while read names; do
        src=$(printf $names | cut -f1)
        dst=$(printf $names | cut -f2)
        [ $src = $dst ] && continue
        [ -e $dst ] && continue
        mv $src $dst
    done
    rm $old $new
    lf -remote "send $id unselect"
}}

# symlink
cmd Link %{{
    for file in $(lf -remote 'load'); do
        if [ ! -n "${mode+1}" ]; then
            mode="$file"
            continue
        fi
        files+=("$file")
    done
    if [ "${#files[@]}" -lt 1 ]; then
        lf -remote "send $id echo no files to link files: ${files}"
        exit 0
    fi
    # symbolically  copy mode is indicating a soft link
    if [[ "$mode" == copy ]]; then
        ln -sr $files -t .
    # while a move mode is indicating a hard link
    elif [[ "$mode" == move ]]; then
        ln $files -t .
    fi
}}

# fzf + zoxide
cmd fzz ${{
    sel=$(zoxide query --list | fzf --no-multi)
    lf -remote "send $id cd \"$sel\""
}}

# ______  ___                      _____
# ___   |/  /_____ ___________________(_)_____________ ________
# __  /|_/ /_  __ `/__  __ \__  __ \_  /__  __ \_  __ `/_  ___/
# _  /  / / / /_/ /__  /_/ /_  /_/ /  / _  / / /  /_/ /_(__  )
# /_/  /_/  \__,_/ _  .___/_  .___//_/  /_/ /_/_\__, / /____/
#                  /_/     /_/                 /____/
# unmap
map d

# general
map . set hidden!
map ; read
map <enter> open
map d delete
map x cut
map R reload
map b $vi $fx

# put lf to background
map <c-z> $ kill -STOP $PPID

# dedicated key for file opener
map o open-with

# fzf
map <c-f> $vi $(fzf)
map <a-f> fzz
map f :fzf_jump

# archives
map ax extract
map aa atool
map az push :zip<space>
map at push :tar<space>

# selection
map <c-v> select-dirs
map <a-v> select-files

# symlink
# y (select for copy) and P to paste soft-link
# d (select for cut) and P to paste hard-link
map P :Link

# bookmarks
map gh cd ~
map gC cd ~/Code
map gD cd ~/Downloads
map gA cd ~/Media
map gU cd ~/Music
map gP cd ~/Pictures
map gV cd ~/Videos
map gf cd ~/.config
map gl cd ~/.local/share
map ge cd /etc
map gb cd /boot
map gu cd /usr/share
map gd cd /dev
map go cd /opt
map gv cd /var
map gm cd /media
map gi cd /run/media
map gM cd /mnt
map gt cd /tmp
map gr cd /
map gs cd /srv
# map gk cd /bedrock/strata
