在启动edit-server插件时,提示No applicable method: frame-creation-function

相关配置:

(use-package edit-server
  :ensure t
  :commands edit-server-start
  :init (if after-init-time
              (edit-server-start)
            (add-hook 'after-init-hook
                      #'(lambda() (edit-server-start))))
  :config (setq edit-server-new-frame-alist
                '((name . "Edit with Emacs FRAME")
                  (top . 200)
                  (left . 200)
                  (width . 80)
                  (height . 25)
                  (minibuffer . t)
                  (menu-bar-lines . t)
                  (window-system . x))))

错误提示:

error in process filter: cl-no-applicable-method: No applicable method: frame-creation-function, ((tool-bar-lines . 0) (vertical-scroll-bars) (font . "-*-Input Mono Narrow-semilight-*-*-*-16-*-*-*-*-*-*-*") (bottom-divider-width . 1) (right-divider-width . 1) (name . "Edit with Emacs FRAME") (top . 200) (left . 200) (width . 80) (height . 25) (minibuffer . t) (menu-bar-lines . t) (window-system . x))
error in process filter: No applicable method: frame-creation-function, ((tool-bar-lines . 0) (vertical-scroll-bars) (font . "-*-Input Mono Narrow-semilight-*-*-*-16-*-*-*-*-*-*-*") (bottom-divider-width . 1) (right-divider-width . 1) (name . "Edit with Emacs FRAME") (top . 200) (left . 200) (width . 80) (height . 25) (minibuffer . t) (menu-bar-lines . t) (window-system . x))

问题出在edit-server-new-frame-alist中指定了参数 (window-system . x),要求在X Window下显示。

如果是Windows,你可以看到,frame-creation-function仅仅特化在(eql window-system nil)或者(eql window-system 'w32)的情况,如下:

如果是Mac,你大概会看到仅仅特化在(eql window-system nil)或者(eql window-system 'ns),这时候是找不到applicable method的。

解决方法:

如果你是直接启动Emacs(没用emacs --daemon启动),或者你是直接启动Emacs,然后在Emacs中自己启动服务器的(通过server-start),那样可以直接不用指定window-system,去掉就行,或者直接指定值为window-system

(setq edit-server-new-frame-alist
      `((name . "Edit with Emacs FRAME")
        (top . 200)
        (left . 200)
        (width . 80)
        (height . 25)
        (minibuffer . t)
        (menu-bar-lines . t)
        ;; 或者下面这句直接去掉
        (window-system . ,window-system)))

但是如果你一开始就通过emacs --daemon等方式启动的话,(window-system)(getenv "DISPLAY"),都会返回nil,没办法知道窗口系统是什么,这时候可能得手动判断系统了,下面是个例子,你可以参考下(只判断了几个系统。。。):

(setq edit-server-new-frame-alist
      `((name . "Edit with Emacs FRAME")
        (top . 200)
        (left . 200)
        (width . 80)
        (height . 25)
        (minibuffer . t)
        (menu-bar-lines . t)
        (window-system . ,(cond
                           ((memq system-type '(cygwin windows-nt)) 'w32)
                           ((eq system-type 'darwin) 'ns)
                           (t 'x)))))

非常感谢,去掉这行(window-system . ,window-system),正常了。

可以使用emacs-chrome 功能了。

不知道有沒有可以置頂emacs 小窗口的方法?

这个不清楚,我搜了一下,也没找到,应该没有提供这个接口, 不过可以依赖外部程序来实现自动置顶,具体方案得看系统是什么。

思路:

修改edit-server包的edit-server-make-frame函数(通过advice等)使得窗口标题有一定的特征,比如edit-server创建的窗口标题统一叫edit-server-01、edit-server-02…这样的,然后通过外部工具,比如Windows下的AutoHotkey,检测到特定特征的窗口,直接让它置顶。Mac下的Hammerspoon查了下好像不能让一个窗口置顶。我建议Ctrl+Tab或者Command + Tab快速在浏览器和Emacs frame之间切换就行(它们两个应该是最近访问窗口,切一下到Eamcs,再切一下到浏览器,如此循环)。

或者Mac下你下个 Afloat,Windows下写个简单的AutoHotkey脚本,手动置顶下Emacs frame。

发现一个好用工具,可以替代emacs-server

感谢推荐,看了下,效果挺不错的,以后我有这个需求了再去配这个插件。

现在不弄主要有几个原因:

  1. 需求不大。
  2. 由于工作原因,我主力系统是Windows,目前该插件依赖的外部脚本并不支持Windows。