如何在evil的:q命令之后自动kill buffer?

我用的是spacemacs,开了一个server。在平常编辑文件之后喜欢直接用 :wq保存并关闭client(像是vim一样)。但是这么做之后只是关闭了frame,并没有kill与之对应的 server buffer 。请问怎么做呢?

注:

  1. 不只是:wq:q :q!也是需要的
  2. 有时候我想只是关闭frame,不kill buffer,所以给delete-frame-hook添加lambda的方法或许不适合。也就是说只有在ex命令的q之下才要kill buffer

谢谢各路大神:smiley:

我好像有思路了,可以用自定义的ex-cmd来替代默认的:q

How can I add a new colon-command to Evil?

等会我试试

server?你的本意是 buffer?


不了解 Spacemacs 跟 Evil,但是使用 emacsclient 编辑文件的话,Emacs 会提示用 C-x # 结束编辑

When done with a buffer, type C-x #

我试了下,用它的话会自动关掉文件所关联的 buffer,如果是用了一个新的 frame 的话,也会自动关闭这个 frame。

确实是buffer,不小心写错了_(:зゝ∠)_


但是如果当前的frame是唯一的frame的话,用C-x #会提示

server-delete-client: Attempt to delete the sole visible or iconified frame

我的spacemacs会在后台开一个进程,所以一般唯一的这个frame我也会关上。用:q的话可以关闭,但是C-x #就不行了

现在遇到了新的问题。

如果我在启动client的时候使用了-c参数(就是每启动一次client都会新建一个frame,如果没有这个参数会重新使用原来的frame),在使用(evil-quit)或者(kill-emacs)(可能是spacemacs的原因,这个函数只会关闭一个frame,不会kill掉emacs的server)或者(delete-frame)关掉frame的时候都会使(menu-bar-menu-frame-live-and-visible-p)变成nil,导致kill-this-buffer失效(在kill-this-buffer的源代码里面如果上面的函数返回nil就不会执行kill buffer的函数)。

但是如果不加这个参数,在某些情况下(具体怎么样还没试出来)在:q的时候会提示Attempt to delete the sole visible or iconified frame;有时候却能正常关闭,即使目前的frame是最后一个frame(貌似有时候后台会出现一个client的进程,这时候就可以关闭最后一个frame了)。

顺带一提,我用的是windows版,client是用emacsclientw.exe启动的,也可能这是windows版独有的bug。

附带上我的配置:(如果不加-c的话其实勉强能用)

(defun liu233w/ex-kill-buffer-and-close ()
  (interactive)
  ;; 只有名称不带*的buffer才会被删除
  (unless (char-equal (elt (buffer-name) 0) ?*)
    (kill-this-buffer))
  ;; (kill-buffer (buffer-name))
  ;; (delete-frame nil t)
  ;; bug:在新建client的时候,不能使用-c参数新建frame,否则,
  ;; (menu-bar-menu-frame-live-and-visible-p)会变成nil,导致kill-this-buffer
  ;; 失效(也就是说连SPC b d都不能用了)。至于为什么那个变成nil
  ;; 会影响kill-this-buffer,请自行查看kill-this-buffer的源代码
  (evil-quit)
  ;; (delete-frame nil t)
  )

(defun liu233w/ex-save-kill-buffer-and-close ()
  (interactive)
  (save-buffer)
  (kill-this-buffer)
  (evil-quit))

(evil-ex-define-cmd "quit" 'liu233w/ex-kill-buffer-and-close)
(evil-ex-define-cmd "wq" 'liu233w/ex-save-kill-buffer-and-close)

敲了这么多字,心好累_(:зゝ∠)_

我刚刚更新了这两个函数,可以在用户拒绝关闭 buffer 的时候(比如说没有保存)不再继续关闭 frame。

(defun liu233w/ex-kill-buffer-and-close ()
  "删除当前buffer并关闭窗口,如果buffer 删除失败(例如没有保存),则不会关闭窗口。"
  (interactive)
  ;; 如果当前的buffer 没有关联文件,则不删除当前buffer
  (if (buffer-file-name)
      (when (kill-buffer)
        (evil-quit))
    (evil-quit)))

(defun liu233w/ex-save-kill-buffer-and-close ()
  "保存当前buffer的内容,删除buffer,并关闭窗口,如果删除失败,则不会关闭窗口。"
  (interactive)
  (save-buffer)
  (when (kill-buffer)
    (evil-quit)))

明明是几个月前的代码,怎么就感觉恍若隔世了呢_(:зゝ∠)_

说明你日均代码量高!

:joy::joy::joy: