Skip to content

Instantly share code, notes, and snippets.

@topisani
Created November 17, 2017 17:42
Show Gist options
  • Save topisani/595944fce5e91887509f6f4c44254458 to your computer and use it in GitHub Desktop.
Save topisani/595944fce5e91887509f6f4c44254458 to your computer and use it in GitHub Desktop.
Cquery for emacs
;;; lsp-cquery.el --- cquery support for lsp-mode -*- lexical-binding: t; -*-
(require 'cc-mode)
(require 'lsp-mode)
(defcustom lsp-cquery-executable
"cquery"
"The cquery executable."
:type '(string)
:group 'lsp-mode)
(defun lsp-cquery--get-root ()
"Return the root directory of a cquery project."
(or (expand-file-name (locate-dominating-file default-directory "compile_commands.json"))
(user-error "Could not find cquery project root")))
(lsp-define-stdio-client lsp-cquery "cquery"
#'lsp-cquery--get-root
(list lsp-cquery-executable "--language-server")
:ignore-regexps '("\\$cquery/")
:docstring "cquery Language Server")
(defun cquery-lsp--start (orig-func client)
(when lsp--cur-workspace
(user-error "LSP mode is already enabled for this buffer"))
(let* ((root (funcall (lsp--client-get-root client)))
(workspace (gethash root lsp--workspaces))
new-conn response init-params
parser proc cmd-proc)
(if workspace
(setq lsp--cur-workspace workspace)
(setf
parser (make-lsp--parser)
lsp--cur-workspace (make-lsp--workspace
:parser parser
:file-versions (make-hash-table :test 'equal)
:root root
:client client)
(lsp--parser-workspace parser) lsp--cur-workspace
new-conn (funcall
(lsp--client-new-connection client)
(lsp--parser-make-filter parser (lsp--client-ignore-regexps client))
(lsp--make-sentinel (current-buffer)))
;; the command line process invoked
cmd-proc (if (consp new-conn) (car new-conn) new-conn)
;; the process we actually communicate with
proc (if (consp new-conn) (cdr new-conn) new-conn)
(lsp--workspace-proc lsp--cur-workspace) proc
(lsp--workspace-cmd-proc lsp--cur-workspace) cmd-proc)
(puthash root lsp--cur-workspace lsp--workspaces)
(run-hooks 'lsp-before-initialize-hook)
(setq init-params `(
:processId ,(emacs-pid) :rootPath ,root
:rootUri ,(concat "file://" root)
:initializationOptions ,`(
:cacheDirectory ,(concat "file://" root ".vscode/cquery_cached_index")
:clientVersion 3)
:capabilities ,(lsp--client-capabilities)))
(setf response (lsp--send-request (lsp--make-request "initialize" init-params)))
(unless response
(signal 'lsp-empty-response-error (list "initialize")))
(setf (lsp--workspace-server-capabilities lsp--cur-workspace)
(gethash "capabilities" response))
;; Version 3.0 now sends an "initialized" notification to allow registration
;; of server capabilities
(lsp--send-notification (lsp--make-notification "initialized" nil))
(run-hooks 'lsp-after-initialize-hook))
(lsp--text-document-did-open)))
(advice-add 'lsp--start :around 'cquery-lsp--start)
(provide 'lsp-cquery)
;;; lsp-cquery.el ends here
@topisani
Copy link
Author

This will break lsp for all other languages. They are upstreaming a change in lsp-mode that will allows this to be very simple

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment