Mercurial > dotfiles
comparison .shell.d/99.safe-paste.zsh @ 531:ec44059d05b0
zsh: update safe-paste logic
| author | Augie Fackler <raf@durin42.com> |
|---|---|
| date | Wed, 25 Mar 2026 21:44:37 -0400 |
| parents | bef29d49d19f |
| children |
comparison
equal
deleted
inserted
replaced
| 530:dbb75edda2ff | 531:ec44059d05b0 |
|---|---|
| 1 # taken from https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/plugins/safe-paste/safe-paste.plugin.zsh | 1 # A good summary of the zsh 5.1 Bracketed Paste Mode changes is at: |
| 2 # Code from Mikael Magnusson: http://www.zsh.org/mla/users/2011/msg00367.html | 2 # https://archive.zhimingwang.org/blog/2015-09-21-zsh-51-and-bracketed-paste.html |
| 3 | |
| 4 # zsh 5.1 (September 2015) introduced built-in support for Bracketed Paste Mode | |
| 5 # https://github.com/zsh-users/zsh/blob/68405f31a043bdd5bf338eb06688ed3e1f740937/README#L38-L45 | |
| 3 # | 6 # |
| 4 # Requires xterm, urxvt, iTerm2 or any other terminal that supports bracketed | 7 # zsh 5.1 breaks url-quote-magic and other widgets replacing self-insert |
| 5 # paste mode as documented: http://www.xfree86.org/current/ctlseqs.html | 8 # zsh-users' bracketed-paste-magic resolves these issues: |
| 9 # https://github.com/zsh-users/zsh/blob/f702e17b14d75aa21bff014168fa9048124db286/Functions/Zle/bracketed-paste-magic#L9-L12 | |
| 6 | 10 |
| 7 # create a new keymap to use while pasting | 11 # Load bracketed-paste-magic if zsh version is >= 5.1 |
| 8 bindkey -N paste | 12 autoload -Uz is-at-least |
| 9 # make everything in this keymap call our custom widget | 13 if is-at-least 5.1; then |
| 10 bindkey -R -M paste "^@"-"\M-^?" paste-insert | 14 set zle_bracketed_paste # Explicitly restore this zsh default |
| 11 # these are the codes sent around the pasted text in bracketed | 15 autoload -Uz bracketed-paste-magic |
| 12 # paste mode. | 16 zle -N bracketed-paste bracketed-paste-magic |
| 13 # do the first one with both -M viins and -M vicmd in vi mode | 17 return ### The rest of this file is NOT executed on zsh version >= 5.1 ### |
| 14 bindkey '^[[200~' _start_paste | 18 fi |
| 15 bindkey -M paste '^[[201~' _end_paste | |
| 16 # insert newlines rather than carriage returns when pasting newlines | |
| 17 bindkey -M paste -s '^M' '^J' | |
| 18 | 19 |
| 19 zle -N _start_paste | 20 ###################################################################### |
| 20 zle -N _end_paste | 21 # The rest of this file is ONLY executed if zsh version < 5.1 |
| 21 zle -N zle-line-init _zle_line_init | 22 ###################################################################### |
| 22 zle -N zle-line-finish _zle_line_finish | |
| 23 zle -N paste-insert _paste_insert | |
| 24 | 23 |
| 25 # switch the active keymap to paste mode | 24 # Code from Mikael Magnusson: https://www.zsh.org/mla/users/2011/msg00367.html |
| 26 function _start_paste() { | 25 # |
| 27 bindkey -A paste main | 26 # Requires xterm, urxvt, iTerm2 or any other terminal that supports |
| 27 # Bracketed Paste Mode as documented: | |
| 28 # https://www.xfree86.org/current/ctlseqs.html#Bracketed%20Paste%20Mode | |
| 29 # | |
| 30 # For tmux, use: bind ] paste-buffer -p | |
| 31 # | |
| 32 # Additional technical details: https://cirw.in/blog/bracketed-paste | |
| 33 | |
| 34 # Create a new keymap to use while pasting | |
| 35 bindkey -N bracketed-paste | |
| 36 # Make everything in this new keymap enqueue characters for pasting | |
| 37 bindkey -RM bracketed-paste '\x00-\xFF' bracketed-paste-enqueue | |
| 38 # These are the codes sent around the pasted text in bracketed paste mode | |
| 39 bindkey -M main '^[[200~' _bracketed_paste_begin | |
| 40 bindkey -M bracketed-paste '^[[201~' _bracketed_paste_end | |
| 41 # Insert newlines rather than carriage returns when pasting newlines | |
| 42 bindkey -M bracketed-paste -s '^M' '^J' | |
| 43 | |
| 44 zle -N _bracketed_paste_begin | |
| 45 zle -N _bracketed_paste_end | |
| 46 zle -N bracketed-paste-enqueue _bracketed_paste_enqueue | |
| 47 | |
| 48 # Attempt to not clobber zle_line_{init,finish} | |
| 49 # Use https://github.com/willghatch/zsh-hooks if available | |
| 50 if typeset -f hooks-add-hook > /dev/null; then | |
| 51 hooks-add-hook zle_line_init_hook _bracketed_paste_zle_init | |
| 52 hooks-add-hook zle_line_finish_hook _bracketed_paste_zle_finish | |
| 53 else | |
| 54 zle -N zle-line-init _bracketed_paste_zle_init | |
| 55 zle -N zle-line-finish _bracketed_paste_zle_finish | |
| 56 fi | |
| 57 | |
| 58 # Switch the active keymap to paste mode | |
| 59 _bracketed_paste_begin() { | |
| 60 # Save the bindkey command to restore the active ("main") keymap | |
| 61 # Tokenise the restorative bindkey command into an array | |
| 62 _bracketed_paste_restore_keymap=( ${(z)"$(bindkey -lL main)"} ) | |
| 63 bindkey -A bracketed-paste main | |
| 28 } | 64 } |
| 29 | 65 |
| 30 # go back to our normal keymap, and insert all the pasted text in the | 66 # Go back to our normal keymap, and insert all the pasted text in the |
| 31 # command line. this has the nice effect of making the whole paste be | 67 # command line. This has the nice effect of making the whole paste be |
| 32 # a single undo/redo event. | 68 # a single undo/redo event. |
| 33 function _end_paste() { | 69 _bracketed_paste_end() { |
| 34 #use bindkey -v here with vi mode probably. maybe you want to track | 70 # Only execute the restore command if it starts with 'bindkey' |
| 35 #if you were in ins or cmd mode and restore the right one. | 71 # Allow for option KSH_ARRAYS being set (indexing starts at 0) |
| 36 bindkey -e | 72 if [ ${_bracketed_paste_restore_keymap[@]:0:1} = 'bindkey' ]; then |
| 37 LBUFFER+=$_paste_content | 73 $_bracketed_paste_restore_keymap |
| 38 unset _paste_content | 74 fi |
| 75 LBUFFER+=$_bracketed_paste_content | |
| 76 unset _bracketed_paste_content _bracketed_paste_restore_keymap | |
| 39 } | 77 } |
| 40 | 78 |
| 41 function _paste_insert() { | 79 # Append a pasted character to the content which is later inserted as a whole |
| 42 _paste_content+=$KEYS | 80 _bracketed_paste_enqueue() { |
| 81 _bracketed_paste_content+=$KEYS | |
| 43 } | 82 } |
| 44 | 83 |
| 45 function _zle_line_init() { | 84 # Run at zle-line-init |
| 46 # Tell terminal to send escape codes around pastes. | 85 _bracketed_paste_zle_init() { |
| 47 [[ $TERM == rxvt-unicode || $TERM == xterm || $TERM = xterm-256color || $TERM = screen || $TERM = screen-256color ]] && printf '\e[?2004h' | 86 _bracketed_paste_content='' |
| 87 # Tell terminal to send escape codes around pastes | |
| 88 if [[ $TERM =~ '^(rxvt-unicode|xterm(-256color)?|screen(-256color)?)$' ]]; then | |
| 89 printf '\e[?2004h' | |
| 90 fi | |
| 48 } | 91 } |
| 49 | 92 |
| 50 function _zle_line_finish() { | 93 # Run at zle-line-finish |
| 51 # Tell it to stop when we leave zle, so pasting in other programs | 94 _bracketed_paste_zle_finish() { |
| 52 # doesn't get the ^[[200~ codes around the pasted text. | 95 # Turn off bracketed paste when we leave ZLE, so pasting in other programs |
| 53 [[ $TERM == rxvt-unicode || $TERM == xterm || $TERM = xterm-256color || $TERM = screen || $TERM = screen-256color ]] && printf '\e[?2004l' | 96 # doesn't get the ^[[200~ codes around the pasted text |
| 97 if [[ $TERM =~ '^(rxvt-unicode|xterm(-256color)?|screen(-256color)?)$' ]]; then | |
| 98 printf '\e[?2004l' | |
| 99 fi | |
| 54 } | 100 } |
| 55 | 101 |
