当 Zsh 行编辑器处于活动状态时使用 Ctrl + C 复制文本

当 Zsh 行编辑器处于活动状态时使用 Ctrl + C 复制文本

我在 Zsh 中添加了一些键盘快捷键来支持选择单词。

为了让选择做一些事情,我想用它Ctrl + C来复制它。不过,Ctrl + C当 Zsh 行编辑器 (ZLE) 未激活时,我还想使用中断程序。

这可能吗?我该怎么做?我试图声明一个function TRAPINTto hook Ctrl + C,但是当我在 ZLE 中并 hit 时Ctrl + C,该函数似乎没有被调用。

答案1

以下代码允许我们使用常用的快捷方式Ctrl + X, Ctrl + C,Ctrl + V来剪切/复制/粘贴到 Zsh 以及 X.org 的剪贴板。

Ctrl + C当我们不在 ZLE 中时,它像往常一样用作中断。为此,我们将钩子插入 Zsh 的precmd_functions&中preexec_functions,以了解何时开始使用 ZLE 进行编辑,以及何时按 完成编辑Enter

为了设置/取消设置Ctrl + C中断信号,我们使用stty.

下面脚本的前部定义了我们的复制/剪切/粘贴剪贴板功能。

后一部分是对优秀答案稍加修改的代码shell - Zsh zle移位选择 - Thinbug,它将键绑定到这些函数。

function zle-clipboard-cut {
  if ((REGION_ACTIVE)); then
    zle copy-region-as-kill
    print -rn -- $CUTBUFFER | xclip -selection clipboard -in
    zle kill-region
  fi
}
zle -N zle-clipboard-cut

function zle-clipboard-copy {
  if ((REGION_ACTIVE)); then
    zle copy-region-as-kill
    print -rn -- $CUTBUFFER | xclip -selection clipboard -in
  else
    # Nothing is selected, so default to the interrupt command
    zle send-break
  fi
}
zle -N zle-clipboard-copy

function zle-clipboard-paste {
  if ((REGION_ACTIVE)); then
    zle kill-region
  fi
  LBUFFER+="$(xclip -selection clipboard -out)"
}
zle -N zle-clipboard-paste

function zle-pre-cmd {
  # We are now in buffer editing mode. Clear the interrupt combo `Ctrl + C` by setting it to the null character, so it
  # can be used as the copy-to-clipboard key instead
  stty intr "^@"
}
precmd_functions=("zle-pre-cmd" ${precmd_functions[@]})

function zle-pre-exec {
  # We are now out of buffer editing mode. Restore the interrupt combo `Ctrl + C`.
  stty intr "^C"
}
preexec_functions=("zle-pre-exec" ${preexec_functions[@]})

# The `key` column is only used to build a named reference for `zle`
for key     kcap    seq           widget              arg (
    cx      _       $'^X'         zle-clipboard-cut   _                     # `Ctrl + X`
    cc      _       $'^C'         zle-clipboard-copy  _                     # `Ctrl + C`
    cv      _       $'^V'         zle-clipboard-paste _                     # `Ctrl + V`
) {
  if [ "${arg}" = "_" ]; then
    eval "key-$key() {
      zle $widget
    }"
  else
    eval "key-$key() {
      zle-$widget $arg \$@
    }"
  fi
  zle -N key-$key
  bindkey ${terminfo[$kcap]-$seq} key-$key
}

相关内容