-
以前の記事は不完全
- import/export以外の定義ジャンプができなかった
- バッファ内の単語を拾う補完しかできなかった
-
上記課題は解決済
- 型推論に基づいて
this.$router
とかを補完できるように <template>
内の変数の定義ジャンプができるように 、lsp-modeの使い方についても学んだため一旦まとめる
- 型推論に基づいて
いらない設定消した
- 下記エラーは修正されていた
Request initialize failed with message: Cannot read property 'config' of null (Internal Error).
- ため、自前で
lsp-register-client
関数を呼び出してLSPサーバを設定していた部分を全削除 - あとvue-modeで出る下記エラー
"Not enabling jit-lock: it does not work in indirect buffer"
- これは無害らしいので、web-modeから再度vue-modeに乗り換えた
ワークスペースにディレクトリ追加
- M-x
lsp-workspace-folders-add
lsp-workspace-folders-add is an interactive compiled Lisp function in
‘~/dotfiles/.emacs.d/elpa/lsp-mode-20190605.1803/lsp-mode.el’.
(lsp-workspace-folders-add PROJECT-ROOT)
Add PROJECT-ROOT to the list of workspace folders.
- プロジェクトルートを追加できる。
.git
とpackage.json
とが別階層にある場合などに必須this.$router
とかが補完効くようになる
computedをderivative: () => {...}
スタイルで書く
-
どういうわけか
derivative() {...}
スタイルだとうまく定義ジャンプできない- 推論の結果が変わるみたい。マジで謎
Windowsで定義ジャンプするとエラー
- elpa/20190605.1803版にて、Windows環境だと定義ジャンプ時にエラーが出る:
Unsupported file scheme d:/Users/wand/Desktop/path/to/sfc/component.vue
- lsp-mode.elの
lsp--uri-to-path
関数の中でエラーが出ている
(defun lsp--uri-to-path (uri)
"Convert URI to a file path."
(let* ((url (url-generic-parse-url (url-unhex-string uri)))
(type (url-type url))
(file (decode-coding-string (url-filename url) locale-coding-system))
(file-name (if (and type (not (string= type "file")))
(if-let ((handler (lsp--get-uri-handler type)))
(funcall handler uri)
(signal 'lsp-file-scheme-not-supported (list uri)))
;; `url-generic-parse-url' is buggy on windows:
;; https://github.com/emacs-lsp/lsp-mode/pull/265
(or (and (eq system-type 'windows-nt)
(eq (elt file 0) ?\/)
(substring file 1))
file))))
(lsp--fix-path-casing
(concat (-some 'lsp--workspace-host-root (lsp-workspaces)) file-name))))
- ここでコケる:
(url (url-generic-parse-url (url-unhex-string uri)))
; #s(url "d" nil nil nil nil "d:/..." nil nil nil nil t ...)
- Vue.jsのSFCを編集すると、定義ジャンプ時にuriに
d:/...
スタイルのパスが渡ってきてしまうようだ url-generic-parse-url
関数はfile:///d:/...
スタイルのURIでないと正常にパースできない- ファイルタイプ
d
と判定され、後続の例外処理に引っかかる
(url (url-generic-parse-url (url-unhex-string uri))) ; #s(url "d" nil nil nil nil "d:/..." nil nil nil nil t ...)
(type (url-type url)) ; "d"
(file-name (if (and type (not (string= type "file"))) ; (string= type "file")がnilに評価され、条件式全体としてtになる
(if-let ((handler (lsp--get-uri-handler type)))
(funcall handler uri)
(signal 'lsp-file-scheme-not-supported (list uri))) ; ここに突入する
回避
- ワークアラウンドとして、
lsp--uri-to-path
関数をオーバライドして回避
;; lsp-modeの関数のバグ修正
;; Vue SFC編集時、file:///スキーマのないパスが渡ってきてしまうことがある
(defun lsp--uri-to-path (uri-or-path)
"Convert URI to a file path."
(let* ((uri (if (and (eq system-type 'windows-nt)
(file-exists-p uri-or-path)
(not (url-file-exists-p uri-or-path)))
(concatenate 'string "file:///" uri-or-path)
uri-or-path))
(url (url-generic-parse-url (url-unhex-string uri)))
(type (url-type url))
(file (decode-coding-string (url-filename url) locale-coding-system))
(file-name (if (and type (not (string= type "file")))
(if-let ((handler (lsp--get-uri-handler type)))
(funcall handler uri)
(signal 'lsp-file-scheme-not-supported (list uri)))
;; `url-generic-parse-url' is buggy on windows:
;; https://github.com/emacs-lsp/lsp-mode/pull/265
(or (and (eq system-type 'windows-nt)
(eq (elt file 0) ?\/)
(substring file 1))
file))))
(lsp--fix-path-casing
(concat (-some 'lsp--workspace-host-root (lsp-workspaces)) file-name))))
(provide 'my-lsp-config)
- 差分
(uri (if (and (eq system-type 'windows-nt)
(file-exists-p uri-or-path)
(not (url-file-exists-p uri-or-path)))
(concatenate 'string "file:///" uri-or-path)
uri-or-path))
-
windows環境に限り、
d:/...
のパスを下記性質を用いて検出file-exists-p
関数はt
に評価されるurl-file-exists-p
関数はnil
に評価される
- 検出したら
file:///
スキーマをつける
課題
-
lsp--uri-to-path
関数は悪くないので呼び出し側を修正すべき- uriを処理する関数にpathが渡ってくるのがおかしい
- 補完がクッソ遅い
Appendix: LSPに関する設定全部
(require 'lsp-mode)
(require 'lsp)
(require 'lsp-clients)
(add-hook 'prog-mode-hook 'lsp)
(add-hook 'vue-mode-hook 'lsp)
(require 'lsp-ui)
(setq-default lsp-prefer-flymake nil
lsp-ui-doc-header t
lsp-ui-doc-include-signature t
lsp-ui-doc-max-height 20
lsp-ui-doc-max-width 30
lsp-ui-doc-use-childframe nil
lsp-ui-doc-use-webkit nil)
(require 'company)
(require 'company-lsp)
(push 'company-lsp company-backends)
;; remap definition jump
;; (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
;; (define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references)
;; remap definition jump
(define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-find-definition)
(define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-find-references)
;; lsp-modeの関数のバグ修正
;; Vue SFC編集時、file:///スキーマのないパスが渡ってきてしまうことがある
(defun lsp--uri-to-path (uri-or-path)
"Convert URI to a file path."
(let* ((uri (if (and (eq system-type 'windows-nt)
(file-exists-p uri-or-path)
(not (url-file-exists-p uri-or-path)))
(concatenate 'string "file:///" uri-or-path)
uri-or-path))
(url (url-generic-parse-url (url-unhex-string uri)))
(type (url-type url))
(file (decode-coding-string (url-filename url) locale-coding-system))
(file-name (if (and type (not (string= type "file")))
(if-let ((handler (lsp--get-uri-handler type)))
(funcall handler uri)
(signal 'lsp-file-scheme-not-supported (list uri)))
;; `url-generic-parse-url' is buggy on windows:
;; https://github.com/emacs-lsp/lsp-mode/pull/265
(or (and (eq system-type 'windows-nt)
(eq (elt file 0) ?\/)
(substring file 1))
file))))
(lsp--fix-path-casing
(concat (-some 'lsp--workspace-host-root (lsp-workspaces)) file-name))))
(provide 'my-lsp-config)