You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Emacs js2-mode的跳转定义功能在其他窗口打开?

让js2-jump-to-definition在其他窗口打开定义的最简方法

要实现这个需求,只需要修改原js2-jump-to-definition函数中的两处核心逻辑:一是跨缓冲区跳转时的窗口处理,二是当前缓冲区找到定义时的窗口拆分逻辑。

修改后的完整代码

(defun js2-jump-to-definition (&optional arg)
  "Jump to the definition of an object's property, variable or function in another window."
  (interactive "P")
  (if (eval-when-compile (fboundp 'xref-push-marker-stack))
      (xref-push-marker-stack)
    (ring-insert find-tag-marker-ring (point-marker)))
  (js2-reparse)
  (let* ((node (js2-node-at-point))
         (parent (js2-node-parent node))
         (names (if (js2-prop-get-node-p parent)
                    (reverse (let ((temp (js2-compute-nested-prop-get parent)))
                               (cl-loop for n in temp with result = '()
                                        do (push n result)
                                        until (equal node n)
                                        finally return result)))))
         node-init)
    (unless (and (js2-name-node-p node)
                 (not (js2-var-init-node-p parent))
                 (not (js2-function-node-p parent)))
      (error "Node is not a supported jump node"))
    (push (or (and names (pop names))
              (unless (and (js2-object-prop-node-p parent)
                           (eq node (js2-object-prop-node-left parent)))
                node))
          names)
    (setq node-init (js2-search-scope node names))
    ;; todo: display list of results in buffer
    ;; todo: group found references by buffer
    (unless node-init
      (switch-to-buffer-other-window ; 修改点1:用其他窗口打开目标缓冲区
       (catch 'found
         (unless arg
           (mapc (lambda (b)
                   (with-current-buffer b
                     (when (derived-mode-p 'js2-mode)
                       (setq node-init (js2-search-scope js2-mode-ast names))
                       (if node-init (throw 'found b)))))
                 (buffer-list)))
         nil)))
    (setq node-init (if (listp node-init) (car node-init) node-init))
    (unless node-init
      (pop-tag-mark)
      (error "No jump location found"))
    ;; 修改点2:当前缓冲区找到定义时,拆分窗口并跳转
    (if (eq (current-buffer) (marker-buffer (js2-node-abs-pos node-init)))
        (progn
          (split-window-sensibly)
          (other-window 1)
          (goto-char (js2-node-abs-pos node-init)))
      (goto-char (js2-node-abs-pos node-init)))))

关键修改说明

  • 跨缓冲区跳转的窗口处理:
    把原代码中的switch-to-buffer替换为switch-to-buffer-other-window,这样当定义在其他缓冲区时,Emacs会自动在新窗口打开目标缓冲区,而不是替换当前窗口。
  • 当前缓冲区定义的窗口处理:
    增加了判断逻辑,如果发现定义就在当前缓冲区,先调用split-window-sensibly(遵循Emacs默认的智能窗口拆分规则),切换到新窗口后再执行goto-char跳转,确保定义在新窗口中显示。

使用方法

将修改后的函数代码复制到你的Emacs配置文件(比如~/.emacs或~/.emacs.d/init.el)中,重启Emacs或者执行M-x eval-buffer加载配置后,按下M-.就会在其他窗口打开定义了。

内容的提问来源于stack exchange,提问作者Xiaorong Liao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:48:46