Vim’s :ls and netrw’s :Ex implementation

Screen Recording 2024-10-19 at 19.24.22

list_buffers.kak

# name: kakoune_list_buffers
# version: 0.1.0
# description: This script provides the functionality to list buffers.
# authors: ["Mathieu Ablasou <alexherbo2@gmail.com>"]
# kakoune: 2023-12-12
# license: MIT
# dependencies: []
# doc: no
# tests: no
define-command list_buffers %{
  evaluate-commands -save-regs '"b' %{
    set-register b %val{bufname}
    edit! -scratch '*buffers*'
    evaluate-commands -no-hooks -buffer '*' %{
      set-register dquote "%val{bufname}:readonly=%opt{readonly}:modified=%val{modified}"
      execute-keys -buffer '*buffers*' 'gep'
    }
    execute-keys 'd'
    try %{
      execute-keys '%<a-s>2<a-F>:H<a-k>\A\Q<c-r>b\E\z<ret>gh'
    } catch %{
      execute-keys 'gg'
    }
    evaluate-commands -draft %{
      execute-keys '%<a-s>H2<a-f>:'
      try %{
        execute-keys -draft 's\A:readonly=false:modified=false\z<ret>d'
      }
      try %{
        execute-keys -draft 's\A:readonly=true:modified=true\z<ret>c (readonly, modified)<esc>'
      }
      try %{
        execute-keys -draft 's\A:readonly=true:modified=false\z<ret>c (readonly)<esc>'
      }
      try %{
        execute-keys -draft 's\A:readonly=false:modified=true\z<ret>c (modified)<esc>'
      }
    }
  }
}

define-command rearrange_buffers %{
  evaluate-commands -buffer '*buffers*' %{
    execute-keys '%<a-s><a-K>^\n<ret>H1s^(.+?)(?: \(.+?\))?$<ret>'
    arrange-buffers %val{selections}
  }
}

add-highlighter shared/buffer_list regions
add-highlighter shared/buffer_list/text default-region fill string
add-highlighter shared/buffer_list/property_list region '^(.+?) \K\(' '\)$' regions
add-highlighter shared/buffer_list/property_list/text default-region group
add-highlighter shared/buffer_list/property_list/text/ regex '\b\w+\b' 0:attribute
add-highlighter shared/buffer_list/property_list/text/ regex '[(),]' 0:operator

hook global BufCreate '\*buffers\*' %{
  set-option buffer filetype buffer_list
}

hook global BufSetOption filetype=buffer_list %{
  add-highlighter buffer/buffer_list ref buffer_list
  map -docstring 'jump to buffers' buffer normal <ret> ':jump_to_buffers<ret>'
  map -docstring 'jump to buffers and close buffer_list buffer' buffer normal <s-ret> ':jump_to_buffers_and_close_buffer_list_buffer<ret>'
}

define-command -hidden jump_to_buffers %{
  evaluate-commands -draft %{
    execute-keys 'x<a-s><a-K>^\n<ret>H1s^(.+?)(?: \(.+?\))?$<ret>'
    evaluate-commands -itersel %{
      evaluate-commands -client %val{client} -verbatim buffer -- %val{selection}
    }
  }
}

define-command -hidden jump_to_buffers_and_close_buffer_list_buffer %{
  jump_to_buffers
  delete-buffer '*buffers*'
}

ls.kak

# name: kakoune_ls
# version: 0.1.0
# description: This script provides the functionality to list directory contents.
# authors: ["Mathieu Ablasou <alexherbo2@gmail.com>"]
# kakoune: 2023-12-12
# license: MIT
# dependencies: ["fifo"]
# doc: no
# tests: no
declare-option str ls_command sh
declare-option str-list ls_args -c %{
  echo ../
  ls -A -p -L -- "$1"
}
declare-option str ls_working_directory

define-command ls -params 0..1 %{
  evaluate-commands %sh{
    case "$#" in
      1)
        if [ -d "$1" ]
        then
          echo 'ls_impl %arg{1}'
        else
          echo 'fail "error: “%arg{1}” is not a directory"'
          exit 1
        fi
        break
        ;;
      0)
        echo 'ls_impl .'
        break
        ;;
    esac
  }
}

define-command -hidden ls_impl -params 1 %{
  evaluate-commands -save-regs '"' %{
    fifo -name '*ls*' -- %opt{ls_command} %opt{ls_args} -- %arg{1}
    set-option buffer ls_working_directory %sh{
      realpath -- "$1"
    }
  }
}

complete-command ls file

add-highlighter shared/ls regex '^[^\n]*/$' 0:value

hook global BufCreate '\*ls\*' %{
  set-option buffer filetype ls
}

hook global BufSetOption filetype=ls %{
  add-highlighter buffer/ls ref ls
  map -docstring 'jump to files or directories' buffer normal <ret> ':jump_to_files_or_directories<ret>'
  map -docstring 'jump to files or directories and close ls buffer' buffer normal <s-ret> ':jump_to_files_or_directories_and_close_ls_buffer<ret>'
}

define-command -hidden jump_to_files_or_directories %{
  evaluate-commands -draft %{
    execute-keys 'x<a-s><a-K>^\n<ret>H'
    evaluate-commands -draft -verbatim try %{
      execute-keys '<a-,><a-K>/\z<ret>'
      evaluate-commands -itersel %{
        evaluate-commands -draft -verbatim edit -existing -- "%opt{ls_working_directory}/%val{selection}"
      }
    }
    evaluate-commands -draft -verbatim try %{
      execute-keys ',<a-K>/\z<ret>'
      evaluate-commands -client %val{client} -verbatim edit -existing -- "%opt{ls_working_directory}/%val{selection}"
    } catch %{
      evaluate-commands -client %val{client} -verbatim ls_impl "%opt{ls_working_directory}/%val{selection}"
    }
  }
}

define-command -hidden jump_to_files_or_directories_and_close_ls_buffer %{
  jump_to_files_or_directories
  delete-buffer '*ls*'
}

explore.kak

# name: kakoune_explore
# version: 0.1.0
# description: This script provides the functionality to explore directory of current file.
# authors: ["Mathieu Ablasou <alexherbo2@gmail.com>"]
# kakoune: 2023-12-12
# license: MIT
# dependencies: ["ls"]
# doc: no
# tests: no
define-command explore -params 0..1 %{
  evaluate-commands %sh{
    case "$#" in
      1)
        echo 'ls %arg{1}'
        break
        ;;
      0)
        echo 'ls %sh{dirname "$kak_buffile"}'
        break
        ;;
    esac
  }
}

complete-command explore file

alias global ex explore

fifo.kak

# name: kakoune_fifo
# version: 0.1.0
# description: This script provides the functionality to create buffers from command outputs.
# authors: ["Mathieu Ablasou <alexherbo2@gmail.com>"]
# kakoune: 2023-12-12
# license: MIT
# dependencies: []
# doc: no
# tests: no
define-command fifo -params 1.. %{
  evaluate-commands %sh{
    fifo_name='*fifo*'
    fifo_flags=
    while :
    do
      case "$1" in
        -name)
          fifo_name="$2"
          shift 2
          ;;
        -scroll)
          fifo_flags='-scroll'
          shift
          ;;
        --)
          shift
          break
          ;;
        *)
          break
          ;;
      esac
    done
    fifo=$(mktemp -u)
    mkfifo "$fifo"
    { "$@" > "$fifo" 2>&1; } < /dev/null > /dev/null 2>&1 &
    cat <<EOF
      edit! ${fifo_flags} -fifo "$fifo" -- "$fifo_name"
      hook -always -once buffer BufCloseFifo "" %{
        nop %sh{
          unlink -- "$fifo"
        }
      }
EOF
  }
}

complete-command fifo shell

alias global ! fifo

buffer_open_directory_hook.kak

# name: kakoune_buffer_open_directory_hook
# version: 0.1.0
# description: This script defines a custom `BufOpenDir` hook.
# authors: ["Mathieu Ablasou <alexherbo2@gmail.com>"]
# kakoune: 2023-12-12
# license: MIT
# dependencies: ["ls"]
# doc: no
# tests: no
define-command add_buffer_open_directory_user_hook -params 1 %{
  hook %arg{1} RuntimeError "1:1: '(?:e|edit|o|open)': (.+): is a directory" %{
    ls %val{hook_param_capture_1}
    trigger-user-hook "BufOpenDir=%val{hook_param_capture_1}"
  }
}
6 Likes