diff options
Diffstat (limited to 'oh-my-zsh/plugins/sudo')
-rw-r--r-- | oh-my-zsh/plugins/sudo/README.md | 75 | ||||
-rw-r--r-- | oh-my-zsh/plugins/sudo/sudo.plugin.zsh | 108 |
2 files changed, 183 insertions, 0 deletions
diff --git a/oh-my-zsh/plugins/sudo/README.md b/oh-my-zsh/plugins/sudo/README.md new file mode 100644 index 0000000..27cd20c --- /dev/null +++ b/oh-my-zsh/plugins/sudo/README.md @@ -0,0 +1,75 @@ +# sudo + +Easily prefix your current or previous commands with `sudo` by pressing <kbd>esc</kbd> twice. + +To use it, add `sudo` to the plugins array in your zshrc file: + +```zsh +plugins=(... sudo) +``` + +## Usage + +### Current typed commands + +Say you have typed a long command and forgot to add `sudo` in front: + +```console +$ apt-get install build-essential +``` + +By pressing the <kbd>esc</kbd> key twice, you will have the same command with `sudo` prefixed without typing: + +```console +$ sudo apt-get install build-essential +``` + +The same happens for editing files with your default editor (defined in `$SUDO_EDITOR`, `$VISUAL` or `$EDITOR`, in that order): + +If the editor defined were `vim`: + +```console +$ vim /etc/hosts +``` + +By pressing the <kbd>esc</kbd> key twice, you will have the same command with `sudo -e` instead of the editor, that would open that editor with root privileges: + +```console +$ sudo -e /etc/hosts +``` + +### Previous executed commands + +Say you want to delete a system file and denied: + +```console +$ rm some-system-file.txt +-su: some-system-file.txt: Permission denied +$ +``` + +By pressing the <kbd>esc</kbd> key twice, you will have the same command with `sudo` prefixed without typing: + +```console +$ rm some-system-file.txt +-su: some-system-file.txt: Permission denied +$ sudo rm some-system-file.txt +Password: +$ +``` + +The same happens for file editing, as told before. + +## Key binding + +By default, the `sudo` plugin uses <kbd>Esc</kbd><kbd>Esc</kbd> as the trigger. +If you want to change it, you can use the `bindkey` command to bind it to a different key: + +```sh +bindkey -M emacs '<seq>' sudo-command-line +bindkey -M vicmd '<seq>' sudo-command-line +bindkey -M viins '<seq>' sudo-command-line +``` + +where `<seq>` is the sequence you want to use. You can find the keyboard sequence +by running `cat` and pressing the keyboard combination you want to use. diff --git a/oh-my-zsh/plugins/sudo/sudo.plugin.zsh b/oh-my-zsh/plugins/sudo/sudo.plugin.zsh new file mode 100644 index 0000000..2a0b3bf --- /dev/null +++ b/oh-my-zsh/plugins/sudo/sudo.plugin.zsh @@ -0,0 +1,108 @@ +# ------------------------------------------------------------------------------ +# Description +# ----------- +# +# sudo or sudo -e (replacement for sudoedit) will be inserted before the command +# +# ------------------------------------------------------------------------------ +# Authors +# ------- +# +# * Dongweiming <ciici123@gmail.com> +# * Subhaditya Nath <github.com/subnut> +# * Marc Cornellà <github.com/mcornella> +# * Carlo Sala <carlosalag@protonmail.com> +# +# ------------------------------------------------------------------------------ + +__sudo-replace-buffer() { + local old=$1 new=$2 space=${2:+ } + + # if the cursor is positioned in the $old part of the text, make + # the substitution and leave the cursor after the $new text + if [[ $CURSOR -le ${#old} ]]; then + BUFFER="${new}${space}${BUFFER#$old }" + CURSOR=${#new} + # otherwise just replace $old with $new in the text before the cursor + else + LBUFFER="${new}${space}${LBUFFER#$old }" + fi +} + +sudo-command-line() { + # If line is empty, get the last run command from history + [[ -z $BUFFER ]] && LBUFFER="$(fc -ln -1)" + + # Save beginning space + local WHITESPACE="" + if [[ ${LBUFFER:0:1} = " " ]]; then + WHITESPACE=" " + LBUFFER="${LBUFFER:1}" + fi + + { + # If $SUDO_EDITOR or $VISUAL are defined, then use that as $EDITOR + # Else use the default $EDITOR + local EDITOR=${SUDO_EDITOR:-${VISUAL:-$EDITOR}} + + # If $EDITOR is not set, just toggle the sudo prefix on and off + if [[ -z "$EDITOR" ]]; then + case "$BUFFER" in + sudo\ -e\ *) __sudo-replace-buffer "sudo -e" "" ;; + sudo\ *) __sudo-replace-buffer "sudo" "" ;; + *) LBUFFER="sudo $LBUFFER" ;; + esac + return + fi + + # Check if the typed command is really an alias to $EDITOR + + # Get the first part of the typed command + local cmd="${${(Az)BUFFER}[1]}" + # Get the first part of the alias of the same name as $cmd, or $cmd if no alias matches + local realcmd="${${(Az)aliases[$cmd]}[1]:-$cmd}" + # Get the first part of the $EDITOR command ($EDITOR may have arguments after it) + local editorcmd="${${(Az)EDITOR}[1]}" + + # Note: ${var:c} makes a $PATH search and expands $var to the full path + # The if condition is met when: + # - $realcmd is '$EDITOR' + # - $realcmd is "cmd" and $EDITOR is "cmd" + # - $realcmd is "cmd" and $EDITOR is "cmd --with --arguments" + # - $realcmd is "/path/to/cmd" and $EDITOR is "cmd" + # - $realcmd is "/path/to/cmd" and $EDITOR is "/path/to/cmd" + # or + # - $realcmd is "cmd" and $EDITOR is "cmd" + # - $realcmd is "cmd" and $EDITOR is "/path/to/cmd" + # or + # - $realcmd is "cmd" and $EDITOR is /alternative/path/to/cmd that appears in $PATH + if [[ "$realcmd" = (\$EDITOR|$editorcmd|${editorcmd:c}) \ + || "${realcmd:c}" = ($editorcmd|${editorcmd:c}) ]] \ + || builtin which -a "$realcmd" | command grep -Fx -q "$editorcmd"; then + __sudo-replace-buffer "$cmd" "sudo -e" + return + fi + + # Check for editor commands in the typed command and replace accordingly + case "$BUFFER" in + $editorcmd\ *) __sudo-replace-buffer "$editorcmd" "sudo -e" ;; + \$EDITOR\ *) __sudo-replace-buffer '$EDITOR' "sudo -e" ;; + sudo\ -e\ *) __sudo-replace-buffer "sudo -e" "$EDITOR" ;; + sudo\ *) __sudo-replace-buffer "sudo" "" ;; + *) LBUFFER="sudo $LBUFFER" ;; + esac + } always { + # Preserve beginning space + LBUFFER="${WHITESPACE}${LBUFFER}" + + # Redisplay edit buffer (compatibility with zsh-syntax-highlighting) + zle redisplay + } +} + +zle -N sudo-command-line + +# Defined shortcut keys: [Esc] [Esc] +bindkey -M emacs '\e\e' sudo-command-line +bindkey -M vicmd '\e\e' sudo-command-line +bindkey -M viins '\e\e' sudo-command-line |