Support // paths in zsh.
With this you can use // to refer to the root of the fuchsia tree in
zsh. For example you could `cd //scripts` or run `//packages/gn/gen.py`.
This is implemented in tab completion by monkey-patching the _path_files
completion function and in the command-line editor by fixing up the
paths in ZLE's accept-line.
This removes the ~f-NAME hack I had before that was slow, ugly and I'm
pretty sure not used by anyone but me.
Change-Id: Id28a720aad47ef73fb6169a3aced3a8f2018ee16
diff --git a/env.sh b/env.sh
index 8b08871..0a92f59 100644
--- a/env.sh
+++ b/env.sh
@@ -726,28 +726,23 @@
if [[ -n "${ZSH_VERSION}" ]]; then
### Zsh Completion
- fpath+=${FUCHSIA_SCRIPTS_DIR}/zsh-completion
+ fpath=(${FUCHSIA_SCRIPTS_DIR}/zsh-completion $fpath[@])
+ # clear cached load of _path_files
+ unfunction _path_files
+ autoload -U _path_files
+ # load and run compinit
autoload -U compinit
compinit
- ### Directory shortcuts for Jiri projects
- # a mapping of jiri project names to paths will be in the associative array fuchsia_projects
- # a directory shortcut ~f-projectname will be present for each project with / replaced by -
- function regenerate_fuchsia_projects() {
- local _update_file=${FUCHSIA_DIR}/.jiri_root/update_history/latest
- local _projects_file=${FUCHSIA_DIR}/.jiri_root/projects.zsh
- if [[ -e $_update_file ]]; then
- if [ $_update_file -nt $_projects_file -o ! -e $_projects_file ]; then
- grep '<project name=' $_update_file | \
- sed -e 's, *<project name="\([^"]*\)" path="\([^"]*\)".*,fuchsia_projects+=(\1 \2),' > \
- $_projects_file
- fi
- . $_projects_file
- fi
+ ### Map paths that start // to $FUCHSIA_DIR
+ function fuchsia::zle::accept-line() {
+ # make a shorter version of $FUCHSIA_DIR using ~
+ local short_dir=${FUCHSIA_DIR/${HOME}/\~}
+ # at the start of the line
+ BUFFER=${BUFFER/#\/\//$short_dir\/}
+ # anywhere in the line
+ BUFFER=${BUFFER// \/\// $short_dir\/}
+ zle .accept-line
}
- typeset -A fuchsia_projects
- regenerate_fuchsia_projects
- for _p in "${(@k)fuchsia_projects}"; do
- hash -d f-${_p//\//-}=$FUCHSIA_DIR/$fuchsia_projects[$_p]
- done
+ zle -N accept-line fuchsia::zle::accept-line
fi
diff --git a/zsh-completion/_path_files b/zsh-completion/_path_files
new file mode 100644
index 0000000..4075b60
--- /dev/null
+++ b/zsh-completion/_path_files
@@ -0,0 +1,28 @@
+#autoload
+
+# Hack to replace _path_files with one that expands // and then calls the
+# original.
+
+local fdir ffile original found_one
+
+# Look for the original _path_files in the $fpath
+for fdir in $fpath; do
+ ffile=$fdir/$0
+ if [[ -e $ffile ]]; then
+ if [[ -z $found_one ]]; then
+ found_one=true
+ else
+ original=$ffile
+ break
+ fi
+ fi
+done
+
+if [[ $PREFIX = //* ]]; then
+ # When we get // replace it with $FUCHSIA_DIR.
+ # But shorten $HOME to ~.
+ local short_dir=${FUCHSIA_DIR/${HOME}/\~}
+ PREFIX=${PREFIX/\/\//${short_dir}\/}
+fi
+
+source $original $*