diff options
Diffstat (limited to '.config/zsh/plugins/manydots-magic')
-rw-r--r-- | .config/zsh/plugins/manydots-magic | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/.config/zsh/plugins/manydots-magic b/.config/zsh/plugins/manydots-magic new file mode 100644 index 0000000..1d02c4e --- /dev/null +++ b/.config/zsh/plugins/manydots-magic @@ -0,0 +1,187 @@ +# -*- mode: sh -*- +# +# manydots-magic - zle tweak for emulating "..."=="../.." etc. +# +# This tweek helps input ancestor directories beyond the parent (`..') +# in a handy way. You can just type triple dots to input `../..', +# quadruple dots to `../../..', etc.. +# +# % .. [Hit <.>] +# % ../.. [Hit <.>] +# % ../../.. [Hit <^H>] +# % ../.. [Hit <^H>] +# % .. +# +# As you see above, each of the `/..' parts complemented by this tweak +# can be deleted by a single invocation of the backward-delete-char +# command, only if invoked right after the magic happens. +# +# % .. [Hit </><.><.>] +# % ../.. [Hit <^H>] +# % ../. +# +# Triple-dot is not a rarely used character sequence, and this tweak +# kind of "knows" when it should be expanded. +# +# % ruby -e '(1.. [Hit <.>] +# % ruby -e '(1... +# +# % git log branch.. [Hit <.>] +# % git log branch... +# +# % git diff .. [Hit <.>] +# % git diff ../.. [Hit <b>] <- This may be a path... +# % git diff ...b [Hit <ranch>] <- Or not. +# % git diff ...branch +# +# Usage: +# autoload -Uz manydots-magic +# manydots-magic +# + +manydots-magic.self-insert() { + emulate -L zsh + local self_insert_function magic_count + zstyle -s ':manydots-magic' self-insert-function self_insert_function + + if [[ "$KEYS" == .* && "$LBUFFER" != *...* && "$LBUFFER" == *.. ]] && { + local -a words + words=("${(@Q)${(z)LBUFFER}}") + # `...` is a wildcard operator in go + [[ ${${(@)words[1,-2]}[(I)go]} = 0 ]] && + [[ $words[-1] == (|*[/=]|[\<\>=]\().. ]] + } + then + [[ "$LASTWIDGET" == (self-insert|backward-delete-char) ]] && + zstyle -s ':manydots-magic' magic-count magic_count + zstyle ':manydots-magic' magic-count $((magic_count+1)) + LBUFFER="$LBUFFER/." + zle "$self_insert_function" + return + fi + + # cancel expansion if it does not seem right + if [[ "$KEYS" != [=/,:\;\|\&\<\>\(\)\[\]{}^~\'\"\`[:space:]]* && + "$LASTWIDGET" == (self-insert|backward-delete-char) && "$LBUFFER" == *../.. ]] && { + zstyle -s ':manydots-magic' magic-count magic_count + [[ "$magic_count" -gt 0 ]] + } + then + repeat $magic_count LBUFFER="${LBUFFER%/..}" + repeat $magic_count LBUFFER="$LBUFFER." + fi + + zstyle ':manydots-magic' magic-count 0 + + zle "$self_insert_function" +} + +manydots-magic.backward-delete-char() { + emulate -L zsh + local backward_delete_char_function + zstyle -s ':manydots-magic' backward-delete-char-function backward_delete_char_function + + if [[ "$LASTWIDGET" == (self-insert|backward-delete-char) && "$LBUFFER" == *../.. ]] && { + local magic_count + zstyle -s ':manydots-magic' magic-count magic_count + [[ "$magic_count" -gt 0 ]] + } + then + zstyle ':manydots-magic' magic-count $((magic_count-1)) + LBUFFER="${LBUFFER%..}" + else + zstyle ':manydots-magic' magic-count 0 + fi + + zle "$backward_delete_char_function" +} + +manydots-magic.on() { + emulate -L zsh + local self_insert_function="${$(zle -lL | awk \ + '$1=="zle"&&$2=="-N"&&$3=="self-insert"{print $4;exit}'):-.self-insert}" + + [[ "$self_insert_function" == manydots-magic.self-insert ]] && + return 0 + + # For url-quote-magic which does not zle -N itself + zle -la "$self_insert_function" || zle -N "$self_insert_function" + + zstyle ':manydots-magic' self-insert-function "$self_insert_function" + + zle -A manydots-magic.self-insert self-insert + + local backward_delete_char_function="$(zle -lL | awk \ + '$1=="zle"&&$2=="-N"&&$3=="backward-delete-char"{print $4;exit}')" + + if [[ -n "$backward_delete_char_function" ]] + then + zle -la "$backward_delete_char_function" || zle -N "$backward_delete_char_function" + else + zle -A backward-delete-char manydots-magic.orig.backward-delete-char + backward_delete_char_function=manydots-magic.orig.backward-delete-char + fi + + zstyle ':manydots-magic' backward-delete-char-function "$backward_delete_char_function" + + zle -A manydots-magic.backward-delete-char backward-delete-char + + zstyle ':manydots-magic' magic-count 0 + + return 0 +} + +manydots-magic.off() { + emulate -L zsh + local self_insert_function backward_delete_char_function + zstyle -s ':manydots-magic' self-insert-function self_insert_function + + [[ -n "$self_insert_function" ]] && + zle -A "$self_insert_function" self-insert + + zstyle -s ':manydots-magic' backward-delete-char-function backward_delete_char_function + + [[ -n "$backward_delete_char_function" ]] && + zle -A "$backward_delete_char_function" backward-delete-char + + zstyle ':manydots-magic' magic-count 0 + + return 0 +} + +zle -N manydots-magic.self-insert +zle -N manydots-magic.backward-delete-char +zle -N manydots-magic.on +zle -N manydots-magic.off + +manydots-magic() { + manydots-magic.on +} + +[[ -o kshautoload ]] || manydots-magic "$@" + +# Copyright (c) 2011, 2012 Akinori MUSHA +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + |