]> src.twobees.de Git - dotfiles.git/blob - stow/oh-my-zsh/.oh-my-zsh/plugins/dirhistory/dirhistory.plugin.zsh
7021fc03a34173f93e5155d038538cc25901331a
[dotfiles.git] / stow / oh-my-zsh / .oh-my-zsh / plugins / dirhistory / dirhistory.plugin.zsh
1 ##
2 #   Navigate directory history using ALT-LEFT and ALT-RIGHT. ALT-LEFT moves back to directories
3 #   that the user has changed to in the past, and ALT-RIGHT undoes ALT-LEFT.
4 #
5 #   Navigate directory hierarchy using ALT-UP and ALT-DOWN.
6 #   ALT-UP moves to higher hierarchy (cd ..)
7 #   ALT-DOWN moves into the first directory found in alphabetical order
8 #
9
10 dirhistory_past=($PWD)
11 dirhistory_future=()
12 export dirhistory_past
13 export dirhistory_future
14
15 export DIRHISTORY_SIZE=30
16
17 # Pop the last element of dirhistory_past.
18 # Pass the name of the variable to return the result in.
19 # Returns the element if the array was not empty,
20 # otherwise returns empty string.
21 function pop_past() {
22   typeset -g $1="${dirhistory_past[$#dirhistory_past]}"
23   if [[ $#dirhistory_past -gt 0 ]]; then
24     dirhistory_past[$#dirhistory_past]=()
25   fi
26 }
27
28 function pop_future() {
29   typeset -g $1="${dirhistory_future[$#dirhistory_future]}"
30   if [[ $#dirhistory_future -gt 0 ]]; then
31     dirhistory_future[$#dirhistory_future]=()
32   fi
33 }
34
35 # Push a new element onto the end of dirhistory_past. If the size of the array
36 # is >= DIRHISTORY_SIZE, the array is shifted
37 function push_past() {
38   if [[ $#dirhistory_past -ge $DIRHISTORY_SIZE ]]; then
39     shift dirhistory_past
40   fi
41   if [[ $#dirhistory_past -eq 0 || $dirhistory_past[$#dirhistory_past] != "$1" ]]; then
42     dirhistory_past+=($1)
43   fi
44 }
45
46 function push_future() {
47   if [[ $#dirhistory_future -ge $DIRHISTORY_SIZE ]]; then
48     shift dirhistory_future
49   fi
50   if [[ $#dirhistory_future -eq 0 || $dirhistory_futuret[$#dirhistory_future] != "$1" ]]; then
51     dirhistory_future+=($1)
52   fi
53 }
54
55 # Called by zsh when directory changes
56 autoload -U add-zsh-hook
57 add-zsh-hook chpwd chpwd_dirhistory
58 function chpwd_dirhistory() {
59   push_past $PWD
60   # If DIRHISTORY_CD is not set...
61   if [[ -z "${DIRHISTORY_CD+x}" ]]; then
62     # ... clear future.
63     dirhistory_future=()
64   fi
65 }
66
67 function dirhistory_cd(){
68   DIRHISTORY_CD="1"
69   cd $1
70   unset DIRHISTORY_CD
71 }
72
73 # Move backward in directory history
74 function dirhistory_back() {
75   local cw=""
76   local d=""
77   # Last element in dirhistory_past is the cwd.
78
79   pop_past cw
80   if [[ "" == "$cw" ]]; then
81     # Someone overwrote our variable. Recover it.
82     dirhistory_past=($PWD)
83     return
84   fi
85
86   pop_past d
87   if [[ "" != "$d" ]]; then
88     dirhistory_cd $d
89     push_future $cw
90   else
91     push_past $cw
92   fi
93 }
94
95
96 # Move forward in directory history
97 function dirhistory_forward() {
98   local d=""
99
100   pop_future d
101   if [[ "" != "$d" ]]; then
102     dirhistory_cd $d
103     push_past $d
104   fi
105 }
106
107
108 # Bind keys to history navigation
109 function dirhistory_zle_dirhistory_back() {
110   # Erase current line in buffer
111   zle .kill-buffer
112   dirhistory_back
113   zle .accept-line
114 }
115
116 function dirhistory_zle_dirhistory_future() {
117   # Erase current line in buffer
118   zle .kill-buffer
119   dirhistory_forward
120   zle .accept-line
121 }
122
123 zle -N dirhistory_zle_dirhistory_back
124 zle -N dirhistory_zle_dirhistory_future
125
126 for keymap in emacs vicmd viins; do
127   # dirhistory_back
128   bindkey -M $keymap "\e[3D" dirhistory_zle_dirhistory_back    # xterm in normal mode
129   bindkey -M $keymap "\e[1;3D" dirhistory_zle_dirhistory_back  # xterm in normal mode
130   bindkey -M $keymap "\e\e[D" dirhistory_zle_dirhistory_back   # Putty
131   bindkey -M $keymap "\eO3D" dirhistory_zle_dirhistory_back    # GNU screen
132
133   case "$TERM_PROGRAM" in
134   Apple_Terminal) bindkey -M $keymap "^[b" dirhistory_zle_dirhistory_back ;; # Terminal.app
135   iTerm.app) bindkey -M $keymap "^[^[[D" dirhistory_zle_dirhistory_back ;;   # iTerm2
136   esac
137
138   if (( ${+terminfo[kcub1]} )); then
139     bindkey -M $keymap "^[${terminfo[kcub1]}" dirhistory_zle_dirhistory_back  # urxvt
140   fi
141
142   # dirhistory_future
143   bindkey -M $keymap "\e[3C" dirhistory_zle_dirhistory_future    # xterm in normal mode
144   bindkey -M $keymap "\e[1;3C" dirhistory_zle_dirhistory_future  # xterm in normal mode
145   bindkey -M $keymap "\e\e[C" dirhistory_zle_dirhistory_future   # Putty
146   bindkey -M $keymap "\eO3C" dirhistory_zle_dirhistory_future    # GNU screen
147
148   case "$TERM_PROGRAM" in
149   Apple_Terminal) bindkey -M $keymap "^[f" dirhistory_zle_dirhistory_future ;; # Terminal.app
150   iTerm.app) bindkey -M $keymap "^[^[[C" dirhistory_zle_dirhistory_future ;;   # iTerm2
151   esac
152
153   if (( ${+terminfo[kcuf1]} )); then
154     bindkey -M $keymap "^[${terminfo[kcuf1]}" dirhistory_zle_dirhistory_future # urxvt
155   fi
156 done
157
158 #
159 # HIERARCHY Implemented in this section, in case someone wants to split it to another plugin if it clashes bindings
160 #
161
162 # Move up in hierarchy
163 function dirhistory_up() {
164   cd .. || return 1
165 }
166
167 # Move down in hierarchy
168 function dirhistory_down() {
169   cd "$(find . -mindepth 1 -maxdepth 1 -type d | sort -n | head -n 1)" || return 1
170 }
171
172
173 # Bind keys to hierarchy navigation
174 function dirhistory_zle_dirhistory_up() {
175   zle .kill-buffer   # Erase current line in buffer
176   dirhistory_up
177   zle .accept-line
178 }
179
180 function dirhistory_zle_dirhistory_down() {
181   zle .kill-buffer   # Erase current line in buffer
182   dirhistory_down
183   zle .accept-line
184 }
185
186 zle -N dirhistory_zle_dirhistory_up
187 zle -N dirhistory_zle_dirhistory_down
188
189 for keymap in emacs vicmd viins; do
190   # dirhistory_up
191   bindkey -M $keymap "\e[3A" dirhistory_zle_dirhistory_up    # xterm in normal mode
192   bindkey -M $keymap "\e[1;3A" dirhistory_zle_dirhistory_up  # xterm in normal mode
193   bindkey -M $keymap "\e\e[A" dirhistory_zle_dirhistory_up   # Putty
194   bindkey -M $keymap "\eO3A" dirhistory_zle_dirhistory_up    # GNU screen
195
196   case "$TERM_PROGRAM" in
197   Apple_Terminal) bindkey -M $keymap "^[[A" dirhistory_zle_dirhistory_up ;;  # Terminal.app
198   iTerm.app) bindkey -M $keymap "^[^[[A" dirhistory_zle_dirhistory_up ;;     # iTerm2
199   esac
200
201   if (( ${+terminfo[kcuu1]} )); then
202     bindkey -M $keymap "^[${terminfo[kcuu1]}" dirhistory_zle_dirhistory_up # urxvt
203   fi
204
205   # dirhistory_down
206   bindkey -M $keymap "\e[3B" dirhistory_zle_dirhistory_down    # xterm in normal mode
207   bindkey -M $keymap "\e[1;3B" dirhistory_zle_dirhistory_down  # xterm in normal mode
208   bindkey -M $keymap "\e\e[B" dirhistory_zle_dirhistory_down   # Putty
209   bindkey -M $keymap "\eO3B" dirhistory_zle_dirhistory_down    # GNU screen
210
211   case "$TERM_PROGRAM" in
212   Apple_Terminal) bindkey -M $keymap "^[[B" dirhistory_zle_dirhistory_down ;;  # Terminal.app
213   iTerm.app) bindkey -M $keymap "^[^[[B" dirhistory_zle_dirhistory_down ;;     # iTerm2
214   esac
215
216   if (( ${+terminfo[kcud1]} )); then
217     bindkey -M $keymap "^[${terminfo[kcud1]}" dirhistory_zle_dirhistory_down # urxvt
218   fi
219 done
220
221 unset keymap