Created
April 2, 2019 17:37
-
-
Save twlz0ne/a34bee2f5b2b62772ebe42756a1fb469 to your computer and use it in GitHub Desktop.
verfify https://github.com/emacs-lsp/lsp-mode/pull/743 #emacs #lsp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; Usage: /path/to/emacs -nw -Q -l /path/to/test-lsp-find-clients.el | |
;;; Preset: | |
;; | |
;; mkdir ~/scratch/c-c++/test-lsp-{clangd,cquery} | |
;; touch ~/scratch/c-c++/test-lsp-{clangd,cquery}/main.cc | |
;; touch ~/scratch/c-c++/test-lsp-clangd/CLANGD | |
;; touch ~/scratch/c-c++/test-lsp-cquery/CQUERY | |
;; | |
;;; Date: 2019-04-02_20.20.27 | |
(toggle-debug-on-error) | |
(global-set-key (kbd "C-h") 'delete-backward-char) | |
(global-set-key (kbd "M-h") 'backward-kill-word) | |
(global-set-key (kbd "<f1>") 'help-command) | |
(define-key isearch-mode-map "\C-h" 'isearch-delete-char) | |
;; ------------------------------------------------------------------ | |
(setq user-emacs-directory (format "~/.emacs.d/%s/%s/" (file-name-base load-file-name) emacs-version)) | |
(setq package-user-dir (concat user-emacs-directory "elpa/")) | |
(unless (load "~/.emacs.d/elpa.el" t) | |
(setq package-archives | |
'(("gnu" . "https://elpa.gnu.org/packages/") | |
("melpa" . "https://melpa.org/packages/")))) | |
(package-initialize) | |
(defun require-packages (&rest packages) | |
(dolist (pkg packages) | |
(unless (package-installed-p pkg) | |
(package-refresh-contents) | |
(package-install pkg)) | |
(require pkg))) | |
;; ------------------------------------------------------------------ | |
;; (setq el-get-dir (concat user-emacs-directory "el-get/")) | |
;; (add-to-list 'load-path (concat el-get-dir "el-get")) | |
;; | |
;; (setq el-get-git-shallow-clone t) | |
;; (setq el-get-byte-compile nil) | |
;; (setq el-get-bundle-byte-compile nil) | |
;; (setq el-get-install-skip-emacswiki-recipes t) | |
;; | |
;; (unless (require 'el-get nil 'noerror) | |
;; (with-current-buffer | |
;; (url-retrieve-synchronously | |
;; "https://raw.githubusercontent.com/dimitri/el-get/master/el-get-install.el") | |
;; (goto-char (point-max)) | |
;; (eval-print-last-sexp))) | |
;; | |
;; (remove-hook 'el-get-post-install-hooks 'el-get-post-install-notification) | |
;; ------------------------------------------------------------------ | |
(require-packages | |
'projectile | |
'lsp-mode | |
'company-lsp | |
'cquery | |
'ivy) | |
(require 'lsp-clients) | |
(require 'cl) | |
(message "\n---------- start init") | |
(defmacro lsp-set-activation-fn (server-id fn) | |
"Store function FN into slot `activation-fn' of client identified by SERVER-ID. | |
\(fn 'example-ls 'example-activation-func)" | |
`(let ((cl-x (gethash ,server-id lsp-clients)) | |
(slot (cl-struct-slot-offset 'lsp--client 'activation-fn))) | |
(assert (and cl-x slot)) | |
(message "==> [lsp-set-activation-fn] server-id: %s, fn: %s" ,server-id ',fn) | |
(aset cl-x slot ,fn))) | |
(defun lsp--find-clients@override (buffer-major-mode file-name) | |
"Fix the misjudgement in original `lsp--find-clients'. | |
If a client has -activation-fn, it should not continue to check -major-modes." | |
(let ((remote? (file-remote-p file-name))) | |
(--when-let (->> lsp-clients | |
hash-table-values | |
(-filter (-lambda (client) | |
(and (or (-some-> client lsp--client-activation-fn (funcall buffer-file-name buffer-major-mode)) | |
(and (not (lsp--client-activation-fn client)) ;; +++ | |
(-contains? (lsp--client-major-modes client) buffer-major-mode) | |
(eq (---truthy? remote?) (---truthy? (lsp--client-remote? client))))) | |
(-some-> client lsp--client-new-connection (plist-get :test?) funcall))))) | |
(lsp-log "Found the following clients for %s: %s" | |
file-name | |
(s-join ", " | |
(-map (lambda (client) | |
(format "(server-id %s, priority %s)" | |
(lsp--client-server-id client) | |
(lsp--client-priority client))) | |
it))) | |
(-let* (((add-on-clients main-clients) (-separate 'lsp--client-add-on? it)) | |
(selected-clients (if-let (main-client (and main-clients | |
(--max-by (> (lsp--client-priority it) | |
(lsp--client-priority other)) | |
main-clients))) | |
(cons main-client add-on-clients) | |
add-on-clients))) | |
(lsp-log "The following clients were selected based on priority: %s" | |
(s-join ", " | |
(-map (lambda (client) | |
(format "(server-id %s, priority %s)" | |
(lsp--client-server-id client) | |
(lsp--client-priority client))) | |
selected-clients))) | |
selected-clients)))) | |
(defun lsp-clangd-active-p (filename mode) | |
(message "==> [lsp-clangd-active-p] file: %s" filename) | |
(let ((active-p | |
(and | |
(eq 'c++-mode mode) | |
(file-exists-p (concat (lsp-workspace-root filename) "CLANGD"))))) | |
(message "==> [lsp-clangd-active-p] active-p: %s" active-p) | |
active-p)) | |
(defun lsp-cquery-active-p (filename mode) | |
(message "==> [lsp-cquery-active-p] file: %s" filename) | |
(let ((active-p | |
(and | |
(eq 'c++-mode mode) | |
(file-exists-p (concat (lsp-workspace-root filename) "CQUERY"))))) | |
(message "==> [lsp-cquery-active-p] active-p: %s" active-p) | |
active-p)) | |
(message "clients: %s" (hash-table-keys lsp-clients)) | |
(message "major-modes[clangd]: %s" (lsp--client-major-modes (gethash 'clangd lsp-clients))) | |
(message "major-modes[cquery]: %s" (lsp--client-major-modes (gethash 'cquery lsp-clients))) | |
(lsp-set-activation-fn 'clangd 'lsp-clangd-active-p) | |
(lsp-set-activation-fn 'cquery 'lsp-cquery-active-p) | |
(add-hook 'c++-mode-hook 'lsp) | |
;; for mac with homebrew | |
(add-to-list 'exec-path "/usr/local/opt/llvm/bin/") | |
(add-hook 'after-init-hook | |
(lambda () | |
(ivy-mode 1) | |
(message "\n---------- after init") | |
;; FIX issue that the role of the `client-activation-fn' is offset | |
(advice-add 'lsp--find-clients :override 'lsp--find-clients@override) | |
;; expected clangd actived | |
(find-file "~/scratch/c-c++/test-lsp-clangd/main.cc") | |
;; expected cquery actived | |
(find-file-other-window "~/scratch/c-c++/test-lsp-cquery/main.cc") | |
)) | |
(run-hooks 'after-init-hook) | |
;;; test-lsp-find-clients.el ends here |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment