3 # This is a implementation of per directory history for zsh, some
4 # implementations of which exist in bash[1,2]. It also implements
5 # a per-directory-history-toggle-history function to change from using the
6 # directory history to using the global history. In both cases the history is
7 # always saved to both the global history and the directory history, so the
8 # toggle state will not effect the saved histories. Being able to switch
9 # between global and directory histories on the fly is a novel feature as far
12 #-------------------------------------------------------------------------------
14 #-------------------------------------------------------------------------------
16 # HISTORY_BASE a global variable that defines the base directory in which the
17 # directory histories are stored
19 #-------------------------------------------------------------------------------
21 #-------------------------------------------------------------------------------
23 # The idea/inspiration for a per directory history is from Stewart MacArthur[1]
24 # and Dieter[2], the implementation idea is from Bart Schaefer on the the zsh
25 # mailing list[3]. The implementation is by Jim Hester in September 2012.
27 # [1]: http://www.compbiome.com/2010/07/bash-per-directory-bash-history.html
28 # [2]: http://dieter.plaetinck.be/per_directory_bash
29 # [3]: http://www.zsh.org/mla/users/1997/msg00226.html
31 ################################################################################
33 # Copyright (c) 2014 Jim Hester
35 # This software is provided 'as-is', without any express or implied warranty.
36 # In no event will the authors be held liable for any damages arising from the
37 # use of this software.
39 # Permission is granted to anyone to use this software for any purpose,
40 # including commercial applications, and to alter it and redistribute it
41 # freely, subject to the following restrictions:
43 # 1. The origin of this software must not be misrepresented; you must not claim
44 # that you wrote the original software. If you use this software in a product,
45 # an acknowledgment in the product documentation would be appreciated but is
48 # 2. Altered source versions must be plainly marked as such, and must not be
49 # misrepresented as being the original software.
51 # 3. This notice may not be removed or altered from any source distribution..
53 ################################################################################
55 #-------------------------------------------------------------------------------
56 # configuration, the base under which the directory histories are stored
57 #-------------------------------------------------------------------------------
59 [[ -z $HISTORY_BASE ]] && HISTORY_BASE="$HOME/.directory_history"
60 [[ -z $HISTORY_START_WITH_GLOBAL ]] && HISTORY_START_WITH_GLOBAL=false
61 [[ -z $PER_DIRECTORY_HISTORY_TOGGLE ]] && PER_DIRECTORY_HISTORY_TOGGLE='^G'
63 #-------------------------------------------------------------------------------
64 # toggle global/directory history used for searching - ctrl-G by default
65 #-------------------------------------------------------------------------------
67 function per-directory-history-toggle-history() {
68 if [[ $_per_directory_history_is_global == true ]]; then
69 _per-directory-history-set-directory-history
70 _per_directory_history_is_global=false
71 print -n "\nusing local history"
73 _per-directory-history-set-global-history
74 _per_directory_history_is_global=true
75 print -n "\nusing global history"
81 autoload per-directory-history-toggle-history
82 zle -N per-directory-history-toggle-history
83 bindkey $PER_DIRECTORY_HISTORY_TOGGLE per-directory-history-toggle-history
85 #-------------------------------------------------------------------------------
86 # implementation details
87 #-------------------------------------------------------------------------------
89 _per_directory_history_directory="$HISTORY_BASE${PWD:A}/history"
91 function _per-directory-history-change-directory() {
92 _per_directory_history_directory="$HISTORY_BASE${PWD:A}/history"
93 mkdir -p ${_per_directory_history_directory:h}
94 if [[ $_per_directory_history_is_global == false ]]; then
95 #save to the global history
97 #save history to previous file
98 local prev="$HISTORY_BASE${OLDPWD:A}/history"
102 #discard previous directory's history
103 local original_histsize=$HISTSIZE
105 HISTSIZE=$original_histsize
107 #read history in new file
108 if [[ -e $_per_directory_history_directory ]]; then
109 fc -R $_per_directory_history_directory
114 function _per-directory-history-addhistory() {
115 # respect hist_ignore_space
116 if [[ -o hist_ignore_space ]] && [[ "$1" == \ * ]]; then
119 print -Sr -- "${1%%$'\n'}"
120 # instantly write history if set options require it.
121 if [[ -o share_history ]] || \
122 [[ -o inc_append_history ]] || \
123 [[ -o inc_append_history_time ]]; then
125 fc -AI $_per_directory_history_directory
127 fc -p $_per_directory_history_directory
131 function _per-directory-history-precmd() {
132 if [[ $_per_directory_history_initialized == false ]]; then
133 _per_directory_history_initialized=true
135 if [[ $HISTORY_START_WITH_GLOBAL == true ]]; then
136 _per-directory-history-set-global-history
137 _per_directory_history_is_global=true
139 _per-directory-history-set-directory-history
140 _per_directory_history_is_global=false
145 function _per-directory-history-set-directory-history() {
147 local original_histsize=$HISTSIZE
149 HISTSIZE=$original_histsize
150 if [[ -e "$_per_directory_history_directory" ]]; then
151 fc -R "$_per_directory_history_directory"
155 function _per-directory-history-set-global-history() {
156 fc -AI $_per_directory_history_directory
157 local original_histsize=$HISTSIZE
159 HISTSIZE=$original_histsize
160 if [[ -e "$HISTFILE" ]]; then
165 mkdir -p ${_per_directory_history_directory:h}
167 #add functions to the exec list for chpwd and zshaddhistory
168 autoload -U add-zsh-hook
169 add-zsh-hook chpwd _per-directory-history-change-directory
170 add-zsh-hook zshaddhistory _per-directory-history-addhistory
171 add-zsh-hook precmd _per-directory-history-precmd
173 # set initialized flag to false
174 _per_directory_history_initialized=false