z_mirror/kak-harpoon

git clone https://git.raiguard.me/z_mirror/kak-harpoon

Caleb HeuerRelocate source to rc directory1818eb2

trunk
4.1 KiB136 linesraw
1declare-option str-list harpoon_files
2
3define-command harpoon-add -docstring "harpoon-add: Add the current file to the list of harpoons" %{
4  evaluate-commands %sh{
5    eval set -- "$kak_quoted_opt_harpoon_files"
6    index=0
7    while [ $# -gt 0 ]; do
8      index=$(($index + 1))
9      if [ "$1" = "$kak_bufname" ]; then
10        echo "fail %{$kak_quoted_bufname is already harpooned at index $index}"
11        exit
12      fi
13      shift
14    done
15    index=$(($index + 1))
16    printf "%s\\n" "
17      set-option -add global harpoon_files $kak_quoted_bufname
18      echo '$index: $kak_bufname'
19    "
20  }
21}
22
23define-command harpoon-nav -params 1 -docstring "harpoon-nav <index>: navigate to the harpoon at <index>" %{
24  evaluate-commands %sh{
25    index=$1
26    eval set -- "$kak_quoted_opt_harpoon_files"
27    eval "bufname=\${$index}"
28    if [ -n "$bufname" ]; then
29      echo "edit '$bufname'"
30      echo "echo '$index: $bufname'"
31    else
32      echo "fail 'No harpoon at index $index'"
33    fi
34  }
35}
36
37define-command harpoon-show-list -docstring "harpoon-show-list: show all harpoons in the *harpoons* buffer" %{
38  evaluate-commands -save-regs dquote %{
39    try %{
40      set-register dquote %opt{harpoon_files}
41      edit -scratch *harpoon*
42      execute-keys -draft '%"_d<a-P>a<ret><esc>I<c-r>#: <esc>gjxd'
43    }
44    try %{ execute-keys ggghwl } catch %{
45      delete-buffer *harpoon*
46      fail "No harpoons are set"
47    }
48  }
49}
50
51define-command -hidden harpoon-update-from-list %{
52  evaluate-commands -save-regs dquote %{
53    try %{
54      execute-keys -draft -save-regs '' '%<a-s><a-k>^\d*:<ret><a-;>;wl<a-l>y'
55      set-option global harpoon_files %reg{dquote}
56      harpoon-show-list
57    } catch %{
58      set-option global harpoon_files
59    }
60    echo "Updated harpoons"
61  }
62}
63
64define-command harpoon-add-bindings -docstring "Add convenient keybindings for navigating harpoons" %{
65  map global normal <a-1> ":harpoon-nav 1<ret>"
66  map global normal <a-2> ":harpoon-nav 2<ret>"
67  map global normal <a-3> ":harpoon-nav 3<ret>"
68  map global normal <a-4> ":harpoon-nav 4<ret>"
69  map global normal <a-5> ":harpoon-nav 5<ret>"
70  map global normal <a-6> ":harpoon-nav 6<ret>"
71  map global normal <a-7> ":harpoon-nav 7<ret>"
72  map global normal <a-8> ":harpoon-nav 8<ret>"
73  map global normal <a-9> ":harpoon-nav 9<ret>"
74
75  map global user h ":harpoon-add<ret>" -docstring "add harpoon"
76  map global user H ":harpoon-show-list<ret>" -docstring "show harpoons"
77}
78
79hook global BufCreate \*harpoon\* %{
80  map buffer normal <ret> ':harpoon-nav %val{cursor_line}<ret>'
81  map buffer normal <esc> ':delete-buffer *harpoon*<ret>'
82  alias buffer write harpoon-update-from-list
83  alias buffer w harpoon-update-from-list
84  add-highlighter buffer/harpoon-indices regex ^\d: 0:function
85}
86
87# State saving - save by PWD and git branch, if any
88
89declare-option str harpoon_state_file
90
91define-command -hidden harpoon-load %{
92  evaluate-commands %sh{
93    if [ -f "$kak_opt_harpoon_state_file" ]; then
94      printf "set-option global harpoon_files "
95      cat "$kak_opt_harpoon_state_file"
96    fi
97  }
98}
99
100define-command -hidden harpoon-save %{
101  evaluate-commands %sh{
102    if [ -z "$kak_opt_harpoon_state_file" ]; then
103      exit
104    fi
105    if [ -z "$kak_quoted_opt_harpoon_files" ]; then
106      rm -f "$kak_opt_harpoon_state_file"
107      exit
108    fi
109    printf "$kak_quoted_opt_harpoon_files" > "$kak_opt_harpoon_state_file"
110  }
111}
112
113define-command -hidden harpoon-check %{
114  evaluate-commands %sh{
115    # Ignore scratch files
116    if [ -z "${kak_buffile%\**\*}" ]; then
117      exit
118    fi
119    git_branch=$(git -C "${kak_buffile%/*}" rev-parse --abbrev-ref HEAD 2>/dev/null)
120    state_file=$(printf "%s" "$PWD-$git_branch" | sed -e 's|_|__|g' -e 's|/|_-|g')
121    state_dir=${XDG_STATE_HOME:-~/.local/state}/kak/harpoon
122    state_path="$state_dir/$state_file"
123    if [ "$state_path" != "$kak_opt_harpoon_state_file" ]; then
124      mkdir -p "$state_dir"
125      printf "%s\\n" "
126        harpoon-save
127        set-option global harpoon_state_file '$state_path'
128        harpoon-load
129      "
130    fi
131  }
132}
133
134hook global FocusIn .* harpoon-check
135hook global WinDisplay .* harpoon-check
136hook global KakEnd .* harpoon-save