AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 445051
Accepted
user938271
user938271
Asked: 2018-05-21 18:06:20 +0800 CST2018-05-21 18:06:20 +0800 CST 2018-05-21 18:06:20 +0800 CST

如何从陷阱中启动 Vim 并在暂停后仍然能够恢复它?

  • 772

我的代码中有以下代码~/.zshrc:

nv() (
  if vim --serverlist | grep -q VIM; then
    if [[ $# -eq 0 ]]; then
      vim
    elif [[ $1 == -b ]]; then
      shift 1
      IFS=' '
      vim --remote "$@"
      vim --remote-send ":argdo setl binary ft=xxd<cr>"
      vim --remote-send ":argdo %!xxd<cr><cr>"
    elif [[ $1 == -d ]]; then
      shift 1
      IFS=' '
      vim --remote-send ":tabnew<cr>"
      vim --remote "$@"
      vim --remote-send ":argdo vsplit<cr>:q<cr>"
      vim --remote-send ":windo diffthis<cr>"
    elif [[ $1 == -o ]]; then
      shift 1
      IFS=' '
      vim --remote "$@"
      vim --remote-send ":argdo split<cr>:q<cr><cr>"
    elif [[ $1 == -O ]]; then
      shift 1
      IFS=' '
      vim --remote "$@"
      vim --remote-send ":argdo vsplit<cr>:q<cr><cr>"
    elif [[ $1 == -p ]]; then
      shift 1
      IFS=' '
      vim --remote "$@"
      vim --remote-send ":argdo tabedit<cr>:q<cr>"
    elif [[ $1 == -q ]]; then
      shift 1
      IFS=' '
      vim --remote-send ":cexpr system('$*')<cr>"
    else
      vim --remote "$@"
    fi
  else
    vim -w /tmp/.vimkeys --servername VIM "$@"
  fi
)

它的目的是安装一个nv函数来启动一个 Vim 实例以及一个 Vim 服务器。如果 Vim 服务器已经在运行,该函数应该将它收到的文件参数发送到服务器。

到目前为止,它运作良好。


我的中有以下映射~/.vimrc:

nno  <silent><unique>  <space>R  :<c-u>sil call <sid>vim_quit_reload()<cr>
fu! s:vim_quit_reload() abort
    sil! update
    call system('kill -USR1 $(ps -p $(ps -p $$ -o ppid=) -o ppid=)')
    qa!
endfu

其目的是通过向USR1父 shell 发送信号来重新启动 Vim。

我也有以下陷阱,~/.zshrc当它捕捉到信号时它会重新启动 Vim USR1。

catch_signal_usr1() {
  trap catch_signal_usr1 USR1
  clear
  vim
}
trap catch_signal_usr1 USR1

到目前为止,它也运作良好。


但我注意到,如果我C-z在 shell 中按 , 挂起 Vim,即使 Vim 进程仍在运行,我也无法恢复它(使用$ fg),因为 shell 没有任何工作。

zshrc这是我能够重现该问题的最小值:

catch_signal_usr1() {
  trap catch_signal_usr1 USR1
  vim
}
trap catch_signal_usr1 USR1
func() {
  vim
}

这是一个最小的vimrc:

nnoremap  <space>R  :call Func()<cr>
function! Func()
    call system('kill -USR1 $(ps -p $(ps -p $$ -o ppid=) -o ppid=)')
    qa!
endfunction

如果我使用以下函数启动 Vim:

$ func

然后,按 重新启动 Vim Space R,然后按 挂起它C-z,一旦我回到 shell,我可以看到 Vim 进程正在运行:

$ ps -efH | grep vim
user     24803 24684 10 03:56 pts/9    00:00:01             vim
user     24990 24684  0 03:56 pts/9    00:00:00             grep vim

但我无法恢复它:

$ fg
fg: no current job

如果我使用$ vim命令而不是$ func函数来启动 Vim,我可以重新启动 Vim 进程,将其挂起并恢复它。问题似乎来自功能$ func。


这是我的环境:

  • vim --version: VIM - Vi IMproved 8.1 由用户编译
  • 操作系统:Ubuntu 16.04.4 LTS
  • 终端模拟器:rxvt-unicode v9.22
  • 终端多路复用器:tmux 2.7
  • $TERM: tmux-256color
  • 外壳:zsh 5.5.1

如何从函数启动 Vim 并在挂起后仍然能够恢复它?


编辑:

更多信息:

(1) 当您键入 Ctrl+Z 时,您的终端上会显示什么?

当我键入时没有显示任何内容C-z。

(A) 如果我用下面的命令启动 Vim,$ vim按下 后会显示C-z:

ubuntu% vim

zsh: suspended  vim

我可以用 恢复$ fg。


(B) 如果我使用以下函数启动 Vim $ func:

ubuntu% func
zsh: suspended  func

我也可以用$ fg.


(C) 如果我使用$ vim命令启动 Vim,然后按 重新启动 Vim Space R:

ubuntu% vim
zsh: suspended  catch_signal_usr1

同样,我可以继续使用$ fg.


(D) 但是,如果我使用该$ func功能启动 Vim 并按 重新启动它Space R:

ubuntu% func
ubuntu%

当我回到提示符时没有显示任何内容,并且我无法使用$ fg.


(2) 如果你输入jobs,你的shell 会说什么?

$ jobs没有输出。这是前四种情况下的输出:

(一个)

ubuntu% jobs
[1]  + suspended  vim

(乙)

ubuntu% jobs
[1]  + suspended (signal)  func

(C)

ubuntu% jobs
[1]  + suspended (signal)  catch_signal_usr1

(四)

ubuntu% jobs
ubuntu%

似乎这个问题zsh至少特定于 up to 5.5.1,因为我无法用 bash 重现4.4。

zsh vim
  • 1 1 个回答
  • 580 Views

1 个回答

  • Voted
  1. Best Answer
    Gilles 'SO- stop being evil'
    2018-05-22T13:18:12+08:002018-05-22T13:18:12+08:00

    问题是从陷阱开始后台作业。这份工作有时似乎会“迷失”。更改vim为vim &有时会保留工作,因此可能存在竞争条件。

    您可以通过不从陷阱开始工作来避免这种情况。在陷阱中设置一个标志,并在陷阱外的precmd钩子中启动 vim。这是您的最小示例的改编。

    restart_vim=
    catch_signal_usr1() {
      trap catch_signal_usr1 USR1
      restart_vim=1
    }
    precmd () {
      if [[ -n $restart_vim ]]; then
        restart_vim=
        vim
      fi
    }
    trap catch_signal_usr1 USR1
    func() {
      vim
    }
    

    您在编辑命令提示符时失去了将 Vim 弹出到前台的能力,但这无论如何都不起作用,因为 vim 和 zsh 将竞争终端。

    在您的真实代码中,您可能会遇到麻烦,因为您是从子 shell 启动 vim。不要nv在子 shell 中运行该函数:使用大括号 { ... } around the body, not parentheses. Uselocal IFS to make theIFS` 变量 local。

    • 1

相关问题

  • 什么情况下路径中最先找到的可执行文件不会被使用

  • 符号链接所有点文件和目录

  • 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _

  • 如何在`zsh`中增加一个动态命名的变量

  • 为什么我不能在 zsh 中定义一个名为 path 的只读变量?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve