Blame view

plugins/dirhistory/dirhistory.plugin.zsh 3.04 KB
093a6c34b   mj   Squashed 'repos/r...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  ## 
  #   Navigate directory history using ALT-LEFT and ALT-RIGHT. ALT-LEFT moves back to directories 
  #   that the user has changed to in the past, and ALT-RIGHT undoes ALT-LEFT.
  # 
  
  dirhistory_past=($PWD)
  dirhistory_future=()
  export dirhistory_past
  export dirhistory_future
  
  export DIRHISTORY_SIZE=30
  
  # Pop the last element of dirhistory_past. 
  # Pass the name of the variable to return the result in. 
  # Returns the element if the array was not empty,
  # otherwise returns empty string.
  function pop_past() {
    eval "$1='$dirhistory_past[$#dirhistory_past]'"
    if [[ $#dirhistory_past -gt 0 ]]; then
      dirhistory_past[$#dirhistory_past]=()
    fi
  }
  
  function pop_future() {
    eval "$1='$dirhistory_future[$#dirhistory_future]'"
    if [[ $#dirhistory_future -gt 0 ]]; then
      dirhistory_future[$#dirhistory_future]=()
    fi
  }
  
  # Push a new element onto the end of dirhistory_past. If the size of the array 
  # is >= DIRHISTORY_SIZE, the array is shifted
  function push_past() {
    if [[ $#dirhistory_past -ge $DIRHISTORY_SIZE ]]; then
      shift dirhistory_past
    fi
    if [[ $#dirhistory_past -eq 0 || $dirhistory_past[$#dirhistory_past] != "$1" ]]; then
      dirhistory_past+=($1)
    fi
  }
  
  function push_future() {
    if [[ $#dirhistory_future -ge $DIRHISTORY_SIZE ]]; then
      shift dirhistory_future
    fi
    if [[ $#dirhistory_future -eq 0 || $dirhistory_futuret[$#dirhistory_future] != "$1" ]]; then
      dirhistory_future+=($1)
    fi
  }
  
  # Called by zsh when directory changes
  function chpwd() {
    push_past $PWD
    # If DIRHISTORY_CD is not set...
    if [[ -z "${DIRHISTORY_CD+x}" ]]; then
      # ... clear future.
      dirhistory_future=()
    fi
  }
  
  function dirhistory_cd(){
    DIRHISTORY_CD="1"
    cd $1
    unset DIRHISTORY_CD
  }
  
  # Move backward in directory history
  function dirhistory_back() {
    local cw=""
    local d=""
    # Last element in dirhistory_past is the cwd.
  
    pop_past cw 
    if [[ "" == "$cw" ]]; then
      # Someone overwrote our variable. Recover it.
      dirhistory_past=($PWD)
      return
    fi
  
    pop_past d
    if [[ "" != "$d" ]]; then
      dirhistory_cd $d
      push_future $cw
    else
      push_past $cw
    fi
  }
  
  
  # Move forward in directory history
  function dirhistory_forward() {
    local d=""
  
    pop_future d
    if [[ "" != "$d" ]]; then
      dirhistory_cd $d
      push_past $d
    fi
  }
  
  
  # Bind keys to history navigation
  function dirhistory_zle_dirhistory_back() {
    # Erase current line in buffer
    zle kill-buffer
    dirhistory_back 
    zle accept-line
  }
  
  function dirhistory_zle_dirhistory_future() {
    # Erase current line in buffer
    zle kill-buffer
    dirhistory_forward
    zle accept-line
  }
  
  zle -N dirhistory_zle_dirhistory_back
  # xterm in normal mode
  bindkey "\e[3D" dirhistory_zle_dirhistory_back
  bindkey "\e[1;3D" dirhistory_zle_dirhistory_back
  # Putty:
  bindkey "\e\e[D" dirhistory_zle_dirhistory_back
  # GNU screen:
  bindkey "\eO3D" dirhistory_zle_dirhistory_back
  
  zle -N dirhistory_zle_dirhistory_future
  bindkey "\e[3C" dirhistory_zle_dirhistory_future
  bindkey "\e[1;3C" dirhistory_zle_dirhistory_future
  bindkey "\e\e[C" dirhistory_zle_dirhistory_future
  bindkey "\eO3C" dirhistory_zle_dirhistory_future