如何使用Emacs在Java和JavaScript中“转到定义”?

dojqjjoe  于 2022-12-10  发布在  Java
关注(0)|答案(4)|浏览(159)

我打算重新使用Emacs作为我的主要编辑器。这里的诀窍是我从来没有真正用Emacs做过大型项目工作。到目前为止,我一直使用Visual Studio,但在我最近的项目中,我使用的是Node(翻译一些CoffeeScript --不是我能改变的)和Java,我想做一个完全的转换。我现在使用IntelliJ/WebStorm,但如果我有这些编辑器中的一些特性,我会愿意将其作为整个销售的一部分。令人惊讶的是,WebStorm中有一个针对CoffeeScript的Go to UsageGo to Declaration特性(我想纯JavaScript也是如此)。
Emacs的老手们是如何以类似的方式遍历代码的,也就是说他们通常是如何Go to UsageGo to Declaration的?Java和JavaScript可能是不同的,但是我想知道用Emacs设置这个的区别和可能的麻烦。

j0pj023g

j0pj023g1#

我不是Emacs的老手,但我确实对Emacs着迷。
对于Java:

  • 语义模式在实践中似乎不起作用,但理论上可以跳到定义
  • evil-mode(有点矫枉过正......)可以跳到定义,与evil-goto-definition配合得很好
  • 这工作得非常好,如果可能的话,我甚至建议将它移植到一个非邪恶的环境中
  • imenu(使用正则表达式引擎查找定义)
  • 已在semantic-ia-fast-jump中用作后备
  • 在变量上似乎不太有效

对于Javascript:Javascript有一些非常复杂的作用域样式,不幸的是,这些样式很常见,所以基于正则表达式的解决方案有时会跳到错误的定义。

  • 语义模式根本不起作用
  • evil-goto-definition(使用正则表达式引擎)一如既往地工作出色
  • imenu(使用正则表达式引擎)
  • 在变量上似乎不太有效
  • Tern是一组(外来的)语义分析器,似乎与Emacs集成得很好

总的来说,如果可以的话,我真的建议你使用邪恶,这是极好的。如果你认为邪恶是,嗯,邪恶,那么:

  • 对于变量,在Java中使用语义ia表示跳转,在JS中使用语义tern表示跳转
  • 对于函数,使用imenu。它在Java和JS上都能很好地工作。

最后,这里有一些代码,我几乎所有的跳转都用到它,它让你选择要跳转到的任何函数,并且使用imenu,所以你可以跳转到当前符号点之外的其他地方。

(defun ido-goto-symbol (&optional symbol-list)
  "refresh imenu and jump to a place in the buffer using ido."
  (interactive)
  (unless (featurep 'imenu)
    (require 'imenu nil t))
  (cond
    ((not symbol-list)
      (let ((ido-mode ido-mode)
             (ido-enable-flex-matching
               (if (boundp 'ido-enable-flex-matching)
                 ido-enable-flex-matching t))
             name-and-pos symbol-names position)
        (unless ido-mode
          (ido-mode 1)
          (setq ido-enable-flex-matching t))
        (while (progn
                 (imenu--cleanup)
                 (setq imenu--index-alist nil)
                 (ido-goto-symbol (imenu--make-index-alist))
                 (setq selected-symbol
                   (ido-completing-read "symbol? " symbol-names))
                 (string= (first imenu--rescan-item) selected-symbol)))
        (unless (and (boundp 'mark-active) mark-active)
          (push-mark nil t nil))
        (setq position (rest (assoc selected-symbol name-and-pos)))
        (cond
          ((overlayp position)
            (goto-char (overlay-start position)))
          (t
            (goto-char position)))))
    ((listp symbol-list)
      (dolist (symbol symbol-list)
        (let (name position)
          (cond
            ((and (listp symbol) (imenu--subalist-p symbol))
              (ido-goto-symbol symbol))
            ((listp symbol)
              (setq name (first symbol))
              (setq position (rest symbol)))
            ((stringp symbol)
              (setq name symbol)
              (setq position
                (get-text-property 1 'org-imenu-marker symbol))))
          (unless (or (null position) (null name)
                    (string= (first imenu--rescan-item) name))
            (add-to-list 'symbol-names name)
            (add-to-list 'name-and-pos (cons name position))))))))

(global-set-key (kbd "m-=") 'ido-goto-symbol)
31moq8wy

31moq8wy2#

我在我的项目文件夹上运行了exuberant ctags,并使用-e作为etags选项。一旦TAGS文件被加载,您可以使用M-.M-,M-*来导航它。包etags-select非常有助于在同名的多个方法中进行选择。
其他有用的查找工具是helm,特别是helm-for-fileshelm-find-files(它可以进入TAGS文件来缩小文件和关键字搜索),以及rgrep。我读到wgrep也是一个很好的搜索和替换工具,但我还没有机会使用它。
当然,在你掌握它之前,它比IntelliJ稍微手动一些。关于切换,你仍然需要一个合适的IDE来调试你的代码,因为我还没有找到解决方案。

uurity8g

uurity8g3#

使用malabar-mode,你可以使用C-c C-v C-y来查找jump-to-thing-at-point。这适用于查找变量定义,也适用于查找类的源代码(只要下载了源jar)。当然,malabar-mode依赖于Maven。

bf1o4zei

bf1o4zei4#

目前实现正确跳转到定义的最好方法是使用LSP插件,lsp-modeeglot都应该支持标准的M-.密钥绑定。

相关问题