Tide, JavaScript智能补全插件
Emacs
字数2035 2018-09-19

LSP (Language Server Protocol) 是微软领导开发的编程语言语法补全和代码分析框架, 好处是全世界黑客都一起开发 LSP 后端, 不论你用的是 Emacs, Vim 还是 Sublime, VSCode, Elicpse, IntelliJ 等编程工具, 都可以享受同等智能的语法补全后端.

Emacs 的 lsp-mode 是LSP协议在Emacs的客户端实现. lsp-mode现在能够很好的支持 C++, Python, Ruby, Golang, Haskell, OCamel, Rust, PHP等语言. 当然也包括 JavaScript.

lsp-mode 对 JavaScript 的默认补全主要靠 javascript-typescript-langserver 这个后端来实现.

tide 使用的是 tsserver, 也就是微软给 VSCode 开发的JavaScript智能补全后端, 可以很好的支持 JavaScript 和 TypeScript.

安装方法

1. 安装 tsserver 补全后端

npm install -g typescript
npm install jquery --save
  1. typescript 这个包会安装 tsserver
  2. jquery –save 这个包安装以后, tsserver 就不会抱怨找不到 JQuery 的 $ 符号了 ;)

2. 安装 tide


```Elisp
(require 'tide)

(dolist (hook (list
               'js2-mode-hook
               'rjsx-mode-hook
               'typescript-mode-hook
               ))
  (add-hook hook (lambda ()
                   ;; 初始化 tide
                   (tide-setup)
                   ;; 当 tsserver 服务没有启动时自动重新启动
                   (unless (tide-current-server)
                     (tide-restart-server))
                   )))

体验

打开 *.js 文件后, tide 会自动把当前目录识别为 root 目录 (这对于大部分的 WebPack 项目来说已经是足够了的)

Tide 补全

其他比较有用的命令:

  1. tide-jump-to-definition: 跳转到函数或变量定义的地方
  2. tide-jump-back: 跳转定义以后再跳转回来
  3. tide-rename-symbol: 语法重命名符号
  4. tide-rename-file: 重命名JS文件

也可以像这样用 tide-references 命令查找符号所有语法引用的地方.

Tide 反向引用

更多命令请参考 Tide github

前面说的 lsp-mode 默认使用 javascript-typescript-langserver 这个后端, 其实换成 typescript-language-server (tsserver 的封装) 也可以达到 tide 的同样效果, 类似的配置如下:

(require 'lsp-typescript)

;; Javascript, Typescript and Flow support for lsp-mode
;;
;; Install:
;;
;; npm install -g typescript
;; npm install -g typescript-language-server
;;
;; Fixed error "[tsserver] /bin/sh: /usr/local/Cellar/node/10.5.0_1/bin/npm: No such file or directory" :
;;
;; sudo ln -s /usr/local/bin/npm /usr/local/Cellar/node/10.5.0_1/bin/npm
;;
(add-hook 'js-mode-hook #'lsp-typescript-enable)
(add-hook 'typescript-mode-hook #'lsp-typescript-enable) ;; for typescript support
(add-hook 'js3-mode-hook #'lsp-typescript-enable) ;; for js3-mode support
(add-hook 'rjsx-mode #'lsp-typescript-enable) ;; for rjsx-mode support

(defun lsp-company-transformer (candidates)
  (let ((completion-ignore-case t))
    (all-completions (company-grab-symbol) candidates)))

(defun lsp-js-hook nil
  (make-local-variable 'company-transformers)
  (push 'lsp-company-transformer company-transformers))

(add-hook 'js-mode-hook 'lsp-js-hook)

备注

请直接使用js-mode, 不要使用 js2-mode 或者基于 js2-mode 的插件(比如 rjsx-mode), js2-mode 会导致编辑 JS 文件时非常非常卡顿.