[c-c++] C/C++ layer refactor to support multiple backends
This commit is contained in:
parent
ab818140d0
commit
d536b36d15
|
@ -1165,8 +1165,7 @@ Other:
|
|||
(thanks to Cormac Cannon, Sergey Litovchuk, Fangrui Song and David Vo)
|
||||
- Fixed =lsp= support for =ccls= server (thanks to Alexander Dalshov)
|
||||
- Added automatic formatting on save using ClangFormat with the variables
|
||||
=c-c++-enable-clang-format-on-save= and =c-c++-enable-clang-support=
|
||||
(thanks to Robbert van der Helm)
|
||||
=c-c++-enable-clang-format-on-save= (thanks to Robbert van der Helm)
|
||||
- Added possible value =no-completion= to =c-c++-enable-rtags-support= flag.
|
||||
This adds the option to opt-out of =company-rtags= while enabling Rtags.
|
||||
- Added option to use =google-c-style= with the variable
|
||||
|
|
|
@ -9,64 +9,67 @@
|
|||
- [[#features][Features:]]
|
||||
- [[#install][Install]]
|
||||
- [[#layer][Layer]]
|
||||
- [[#default-mode-for-header-files][Default mode for header files]]
|
||||
- [[#backends][Backends]]
|
||||
- [[#rtags][RTags]]
|
||||
- [[#external-dependencies][External dependencies]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#lsp][LSP]]
|
||||
- [[#features-1][Features]]
|
||||
- [[#external-dependencies-1][External dependencies]]
|
||||
- [[#external-dependencies][External dependencies]]
|
||||
- [[#clangd][clangd]]
|
||||
- [[#ccls-server][ccls server]]
|
||||
- [[#cquery-server][cquery server]]
|
||||
- [[#configuration-1][Configuration]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#basic][Basic]]
|
||||
- [[#selecting-an-alternate-lsp-server][Selecting an alternate LSP server]]
|
||||
- [[#setting-path-to-backend-executable][Setting path to backend executable]]
|
||||
- [[#semantic-highlighting][Semantic highlighting]]
|
||||
- [[#cache-directory-absolute-or-relative][Cache directory (absolute or relative)]]
|
||||
- [[#additional-configuration-options][Additional configuration options]]
|
||||
- [[#example-dotspacemacs-configuration-layers-entry][Example dotspacemacs-configuration-layers entry]]
|
||||
- [[#completion][Completion]]
|
||||
- [[#debugger-dap-integration][Debugger (dap integration)]]
|
||||
- [[#rtags][rtags]]
|
||||
- [[#external-dependencies-1][External dependencies]]
|
||||
- [[#configuration-1][Configuration]]
|
||||
- [[#default-mode-for-header-files][Default mode for header files]]
|
||||
- [[#organize-file-header-includes-on-save][Organize file header includes on save]]
|
||||
- [[#clang-configuration][Clang Configuration]]
|
||||
- [[#clang-format][clang-format]]
|
||||
- [[#company-clang-and-flycheck][Company-clang and flycheck]]
|
||||
- [[#clang-format][clang-format]]
|
||||
- [[#enable-google-set-c-style][Enable google-set-c-style]]
|
||||
- [[#newlines][Newlines]]
|
||||
- [[#projectile-sub-project-adoption][Projectile sub-project adoption]]
|
||||
- [[#key-bindings][Key bindings]]
|
||||
- [[#formatting-clang-format][Formatting (clang-format)]]
|
||||
- [[#rtags-1][RTags]]
|
||||
- [[#lsp-1][LSP]]
|
||||
- [[#cquery--ccls][cquery / ccls]]
|
||||
- [[#backend-language-server][backend (language server)]]
|
||||
- [[#goto][goto]]
|
||||
- [[#cquery--ccls][cquery / ccls]]
|
||||
- [[#backend-language-server][backend (language server)]]
|
||||
- [[#goto][goto]]
|
||||
- [[#gotohierarchy][goto/hierarchy]]
|
||||
- [[#gotomember][goto/member]]
|
||||
- [[#debugger][debugger]]
|
||||
- [[#debugger][debugger]]
|
||||
- [[#rtags-1][RTags]]
|
||||
- [[#additional-key-bindings][Additional key-bindings]]
|
||||
- [[#disassemble][Disassemble]]
|
||||
- [[#formatting-clang-format][Formatting (clang-format)]]
|
||||
- [[#open-matching-files][Open matching files]]
|
||||
- [[#refactor][Refactor]]
|
||||
|
||||
* Description
|
||||
This layer adds configuration for C/C++ language.
|
||||
|
||||
** Features:
|
||||
- Support syntax checking via flycheck with Clang.
|
||||
- Support for disassembly of code with [[https://github.com/jart/disaster][disaster]].
|
||||
- Multiple backends support:
|
||||
- LSP with either =clangd=, [[https://github.com/cquery-project/cquery][cquery]] or [[https://github.com/MaskRay/ccls][ccls]]
|
||||
- [[https://github.com/Andersbakken/rtags][rtags]] (gtags)
|
||||
- [[https://github.com/abingham/emacs-ycmd][emacs-ycmd]]
|
||||
- Support for debuggers [[https://github.com/realgud/realgud][realgud]] and [[https://github.com/emacs-lsp/dap-mode][dap]] (with LSP backend)
|
||||
- Support syntax checking via flycheck (=syntax-checking= layer required)
|
||||
- Auto-completion via company (=auto-completion= layer required)
|
||||
- Support code reformatting with [[http://clang.llvm.org/docs/ClangFormat.html][clang-format]].
|
||||
- Display function or variable definition at the bottom. (when =semantic= layer
|
||||
is included)
|
||||
- Display current function cursor is in at the top. See [[https://github.com/tuhdo/semantic-stickyfunc-enhance][stickyfunc-demos]] for
|
||||
demos in some programming languages. (when =semantic= layer is included)
|
||||
- Support common refactoring with [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]]. See [[https://github.com/tuhdo/semantic-refactor/blob/master/srefactor-demos/demos.org][srefactor-demos]] for
|
||||
demonstration of refactoring features. (when =semantic= layer is included)
|
||||
- Support code navigation via cscope (when =cscope= layer is included) and gtags.
|
||||
- Support auto-completion (when =auto-completion= layer is included) via
|
||||
company-clang (when =c-c++-enable-clang-support= is turned on), or
|
||||
company-ycmd (when =ycmd= layer is included).
|
||||
- Support for [[https://github.com/realgud/realgud][realgud]] debugger.
|
||||
- Support for [[https://github.com/Andersbakken/rtags][rtags]].
|
||||
- Support for [[https://github.com/cquery-project/cquery][cquery]] or [[https://github.com/MaskRay/ccls][ccls]] as an lsp backend.
|
||||
- Support for disassembly of code with [[https://github.com/jart/disaster][disaster]].
|
||||
- =sematic= layer integration:
|
||||
- Function or variable definition at the bottom
|
||||
- Current function cursor is in at the top. See [[https://github.com/tuhdo/semantic-stickyfunc-enhance][stickyfunc-demos]] for
|
||||
demos in some programming languages.
|
||||
- Support common refactoring with [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]]. See [[https://github.com/tuhdo/semantic-refactor/blob/master/srefactor-demos/demos.org][srefactor-demos]] for
|
||||
demonstration of refactoring features.
|
||||
- =cscope= layer integration:
|
||||
- code navigation
|
||||
|
||||
* Install
|
||||
** Layer
|
||||
|
@ -74,7 +77,171 @@ To use this configuration layer, add it to your =~/.spacemacs=. You will need to
|
|||
add =c-c++= to the existing =dotspacemacs-configuration-layers= list in this
|
||||
file.
|
||||
|
||||
*Note:* [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]] is only available for Emacs 24.4+
|
||||
** Backends
|
||||
Supported backends are:
|
||||
- =lsp-clangd= using clangd LSP server
|
||||
- =lsp-ccls= using ccls LSP server
|
||||
- =lsp-cquery= using cquery LSP server
|
||||
- =rtags= using [[https://github.com/Andersbakken/rtags][rtags]]
|
||||
- =ycmd= using [[https://github.com/abingham/emacs-ycmd][emacs-ycmd]]
|
||||
|
||||
To choose a default backend set the layer variable =c-c++-backend=:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(c-c++ :variables =c-c++-backend= 'lsp-clangd)
|
||||
#+END_SRC
|
||||
|
||||
Alternatively the =lsp-clangd= backend will be automatically chosen if the layer
|
||||
=lsp= is used and you did not specify any value for =c-c++-backend=.
|
||||
|
||||
*Note:* It is recommended to use a modern backend like the =lsp= ones.
|
||||
|
||||
Backend can be chosen on a per project basis using directory local variables
|
||||
(files named =.dir-locals.el= at the root of a project), an example to use the
|
||||
=lsp-ccls= backend:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;;; Directory Local Variables
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((c++-mode (c-c++-backend . lsp-ccls)))
|
||||
#+END_SRC
|
||||
|
||||
*Note:* you can easily add a directory local variable with ~SPC f v d~.
|
||||
|
||||
*** LSP
|
||||
LSP support is provided via the [[file:../../+tools/lsp/README.org][LSP layer]], using one of three available backends
|
||||
(all based on libclang).
|
||||
- [[https://clang.llvm.org/extra/clangd/][clangd]]
|
||||
- [[https://github.com/cquery-project/cquery][cquery]]
|
||||
- [[https://github.com/MaskRay/ccls][ccls]]
|
||||
They claim to be more efficient than existing tools at indexing large code bases.
|
||||
|
||||
**** Features
|
||||
- Cross references (definitions, references, base/derived classes/methods, type instances, ...)
|
||||
- Diagnostics
|
||||
- Completion with =company-lsp=
|
||||
- Semantic highlighting (=cquery=, =ccls=)
|
||||
- See more on [[https://github.com/cquery-project/cquery/wiki/Emacs]]
|
||||
- Cross-platform - functional on Windows, Linux and macOS.
|
||||
|
||||
**** External dependencies
|
||||
Install one (or more) of the following (=clangd= is used by default):
|
||||
|
||||
***** clangd
|
||||
Install =clang= using a binary distribution downloaded from the [[http://releases.llvm.org/download.html][LLVM releases
|
||||
page]] or via your package manager. This is the default implementation used by the
|
||||
emacs =lsp-mode= package and probably the easiest to install.
|
||||
- [[https://clang.llvm.org/extra/clangd/Extensions.html][clangd protocol extensions page]]
|
||||
|
||||
***** ccls server
|
||||
Install the =ccls= server. See [[https://github.com/MaskRay/ccls/wiki][instructions]]. This is currently the most fully
|
||||
featured implementation, including semantic highlighting and some navigation/
|
||||
introspection features not provided by clangd.
|
||||
|
||||
Note that prebuild binaries exist for most Linux distros and MacOS using
|
||||
Homebrew.
|
||||
|
||||
***** cquery server
|
||||
Install the =cquery= server. See [[https://github.com/cquery-project/cquery/wiki][instructions]]. This implementation appears to be
|
||||
unmaintained and continued support is provided here purely for existing users.
|
||||
It is recommended to use the =lsp-ccls= backend instead if you can.
|
||||
|
||||
Note that prebuild binaries exist for most Linux distros and MacOS using
|
||||
Homebrew.
|
||||
|
||||
**** Configuration
|
||||
***** Basic
|
||||
To use the default =clangd= language server, select =lsp-clangd= as the =c-c++=
|
||||
layer backend by adding the following to your dotfile:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables c-c++-backend 'lsp-clangd)))
|
||||
#+END_SRC
|
||||
|
||||
***** Selecting an alternate LSP server
|
||||
To choose an alternate LSP server set the layer variable =c-c++-backend= to
|
||||
another supported backend, for instance =lsp-ccls=:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables c-c++-backend 'lsp-ccls)))
|
||||
#+END_SRC
|
||||
|
||||
***** Semantic highlighting
|
||||
Currently only available for =lsp-ccls= and =lps-cquery=. Semantic highlighting
|
||||
can precisely highlight identifiers.
|
||||
|
||||
Semantic highlighting is disabled by default. To enable it set the layer
|
||||
=c-c++-lsp-enable-semantic-highlight= to non-nil. It is possible to give a
|
||||
different color for each identifier by setting the variable to ='rainbow=.
|
||||
|
||||
When semantic highlighting is enabled the method used to highlight the text
|
||||
relies on the =font-lock= mechanism of Emacs which is the fastest. More
|
||||
accurate but also slower method is to use the overlays. To use the overlays set
|
||||
the layer variable =c-c++-lsp-semantic-highlight-method= to ='overlay=.
|
||||
|
||||
***** Cache directory (absolute or relative)
|
||||
Currently only available for =lsp-ccls= and =lps-cquery=.
|
||||
|
||||
All LSP backends are configured to store their index cache in a subdirectory of
|
||||
=.emacs.d/cache=. This can be overridden by specifying an explicit
|
||||
=c-c++-lsp-cache-dir=. Setting this value to a relative path will cause the
|
||||
index cache to be placed in a subdirectory of your current project root.
|
||||
|
||||
***** Additional configuration options
|
||||
See the full list of configuration options you can set at:
|
||||
- [[https://github.com/MaskRay/ccls/wiki/Emacs][Emacs section of =ccls= wiki]]
|
||||
- [[https://github.com/cquery-project/cquery/wiki/Emacs][Emacs section of =cquery= wiki]]
|
||||
|
||||
***** Example dotspacemacs-configuration-layers entry
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables
|
||||
c-c++-adopt-subprojects t
|
||||
c-c++-backend 'lsp-ccls
|
||||
c-c++-lsp-executable (file-truename "~/dev/cpp/ccls/Release/ccls")
|
||||
c-c++-lsp-enable-semantic-highlight 'rainbow)))
|
||||
#+END_SRC
|
||||
|
||||
**** Completion
|
||||
=company-lsp= provides completion functionality. Client-side cache and sorting
|
||||
have been disabled in favour of server,
|
||||
as recommended by =cquery=/=ccls= wikis.
|
||||
|
||||
**** Debugger (dap integration)
|
||||
To install the debug adapter you may run =M-x dap-gdb-lldb-setup= when you are
|
||||
on Linux or download it manually from [[https://marketplace.visualstudio.com/items?itemName=webfreak.debug][Native Debug]] and adjust the
|
||||
=dap-gdb-lldb-path= variable.
|
||||
|
||||
*** rtags
|
||||
rtags is a well established clang-based source code indexing tool.
|
||||
|
||||
**** External dependencies
|
||||
Install the RTags server via [[https://formulae.brew.sh/formula/rtags][homebrew]], the [[https://aur.archlinux.org/packages/rtags/][aur]] or from source according to the
|
||||
instructions [[https://github.com/Andersbakken/rtags][here]]. N.B. RTags is not supported on Windows at the time of
|
||||
writing, although there is an [[https://github.com/Andersbakken/rtags/issues/770][open issue with some recent activity]] on github.
|
||||
|
||||
**** Configuration
|
||||
To enable support for =rtags=, set the layer variable =c-c++-backend=:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables c-c++-backend 'rtags)))
|
||||
#+END_SRC
|
||||
|
||||
This will also enable =company-rtags= to be used as a backend for
|
||||
auto-completion (when =auto-completion= layer is included).
|
||||
To prevent this, while retaining the rest of Rtags functionality,
|
||||
set the variable =c-c++-rtags-completion= to =nil=:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables
|
||||
c-c++-backend 'rtags
|
||||
c-c++-enable-rtags-completion nil)))
|
||||
#+END_SRC
|
||||
|
||||
** Default mode for header files
|
||||
Mode for header files is auto detected by `c-or-c++-mode' in Emacs > 26.1+.
|
||||
|
@ -90,150 +257,6 @@ Older Emacs will open header files in =c-mode= by default, you can open them in
|
|||
variable at the root of your project. More info on directory local variables
|
||||
can be found in the [[http://www.gnu.org/software/emacs/manual/html_node/elisp/Directory-Local-Variables.html][dir-locals]].
|
||||
|
||||
** Backends
|
||||
This layer supports the selection of RTags, or one of three available implementations
|
||||
of the [[https://github.com/Microsoft/language-server-protocol][Language Server Protocol]]
|
||||
for code navigation etc. via the =c-c++-backend= configuration variable.
|
||||
|
||||
*** RTags
|
||||
RTags is a well established clang-based source code indexing tool.
|
||||
|
||||
**** External dependencies
|
||||
Install the RTags server via [[https://formulae.brew.sh/formula/rtags][homebrew]], the [[https://aur.archlinux.org/packages/rtags/][aur]] or from source according to the
|
||||
instructions [[https://github.com/Andersbakken/rtags][here]]. N.B. RTags is not supported on Windows at the time of
|
||||
writing, although there is an [[https://github.com/Andersbakken/rtags/issues/770][open issue with some recent activity]] on github.
|
||||
|
||||
**** Configuration
|
||||
To enable support for =rtags=, set the layer variable =c-c++-backend=:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables c-c++-backend 'rtags)))
|
||||
#+END_SRC
|
||||
|
||||
This will also enable =company-rtags= to be used as a backend for
|
||||
auto-completion (when =auto-completion= layer is included).
|
||||
To prevent this, while retaining the rest of Rtags functionality,
|
||||
set the variable =c-c++-rtags-completion= to =nil=:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables
|
||||
c-c++-backend 'rtags
|
||||
c-c++-enable-rtags-completion nil)))
|
||||
#+END_SRC
|
||||
|
||||
*** LSP
|
||||
LSP support is provided via the [[file:../../+tools/lsp/README.org][LSP layer]], using one of three available backends (all based on libclang).
|
||||
- [[https://clang.llvm.org/extra/clangd/][clangd]]
|
||||
- [[https://github.com/cquery-project/cquery][cquery]]
|
||||
- [[https://github.com/MaskRay/ccls][ccls]]
|
||||
They claim to be more efficient than existing tools at indexing large code bases.
|
||||
|
||||
**** Features
|
||||
- Cross references (definitions, references, base/derived classes/methods, type instances, ...)
|
||||
- Diagnostics
|
||||
- Completion with =company-lsp=
|
||||
- Semantic highlighting (=cquery=, =ccls=)
|
||||
- See more on [[https://github.com/cquery-project/cquery/wiki/Emacs]]
|
||||
- Cross-platform - functional on Windows, Linux and macOS.
|
||||
|
||||
**** External dependencies
|
||||
Install one (or more) of the following (=clangd= is used by default) :
|
||||
|
||||
***** clangd
|
||||
Install =clang= using a binary distribution downloaded from the [[http://releases.llvm.org/download.html][LLVM releases page]] or via your package manager.
|
||||
This is the default implementation used by the emacs =lsp-mode= package and probably the easiest to install.
|
||||
- [[https://clang.llvm.org/extra/clangd/Extensions.html][clangd protocol extensions page]]
|
||||
|
||||
***** ccls server
|
||||
Install the =ccls= server. [[https://github.com/MaskRay/ccls/wiki/Getting-started][Instructions]].
|
||||
This is currently the most fully featured implementation, including semantic highlighting and some navigation/
|
||||
introspection features not provided by clangd.
|
||||
|
||||
***** cquery server
|
||||
Install the =cquery= server. [[https://github.com/cquery-project/cquery/wiki/Getting-started][Instructions]].
|
||||
This implementation appears to be unmaintained, and continued support is provided here purely for existing users.
|
||||
|
||||
**** Configuration
|
||||
***** Basic
|
||||
To use the default =clangd= language server, simply select =lsp= as the =c-c++= layer backend by adding the
|
||||
following to your dotfile:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables c-c++-backend 'lsp)))
|
||||
#+END_SRC
|
||||
|
||||
N.B. The [[file:../../+tools/lsp/README.org][LSP layer]] will be loaded automatically.
|
||||
|
||||
***** Selecting an alternate LSP server
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables c-c++-backend 'lsp c-c++-lsp-server 'ccls))) ; or 'cquery or 'clangd
|
||||
#+END_SRC
|
||||
|
||||
***** Setting path to backend executable
|
||||
The basic configuration above should work if the cquery/ccls executable folder
|
||||
is present in your path. If not, you can set the path explicitly.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables
|
||||
c-c++-backend 'lsp
|
||||
c-c++-server 'ccls
|
||||
c-c++-lsp-executable "/path/to/bin/ccls/clangd/or/cquery")))
|
||||
#+END_SRC
|
||||
|
||||
If you need to expand =~= in the path, you can use =file-truename= like
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables
|
||||
c-c++-backend 'lsp
|
||||
c-c++-server 'ccls
|
||||
c-c++-lsp-executable (file-truename "~/bin/clangd/ccls/or/cquery"))))
|
||||
#+END_SRC
|
||||
|
||||
***** Semantic highlighting :ccls:cquery:
|
||||
Semantic highlighting is disabled by default. To enable, set the
|
||||
=c-c++-lsp-sem-highlight-method= variable to either ='font-lock= or ='overlay=.
|
||||
To enable the rainbow semantic highlighting colour theme, set
|
||||
=c-c++-lsp-sem-highlight-rainbow= to =t=.
|
||||
|
||||
***** Additional configuration options :ccls:cquery:
|
||||
Both lsp backends are configured to store their index cache in a subdirectory of
|
||||
=.emacs.d/cache=. This can be overridden by specifying an explicit
|
||||
=c-c++-lsp-cache-dir=. Setting this value to a relative path will cause the
|
||||
index cache to be placed in a subdirectory of your project root.
|
||||
|
||||
There are other initialization options such as the number of indexer threads,
|
||||
cache serialization format. They have good default values. See =config.el= of
|
||||
the layer and the backends' respective homepages for more info.
|
||||
- [[https://github.com/MaskRay/ccls/wiki/Emacs][Emacs section of =ccls= wiki]]
|
||||
- [[https://github.com/cquery-project/cquery/wiki/Emacs][Emacs section of =cquery= wiki]]
|
||||
|
||||
***** Example dotspacemacs-configuration-layers entry
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables
|
||||
c-c++-adopt-subprojects t
|
||||
c-c++-backend 'lsp
|
||||
c-c++-server 'ccls
|
||||
c-c++-lsp-executable (file-truename "~/dev/cpp/ccls/Release/ccls")
|
||||
c-c++-lsp-sem-highlight-rainbow t)))
|
||||
#+END_SRC
|
||||
|
||||
**** Completion
|
||||
=company-lsp= provides completion functionality. Client-side cache and sorting
|
||||
have been disabled in favour of server,
|
||||
as recommended by =cquery=/=ccls= wikis.
|
||||
|
||||
**** Debugger (dap integration)
|
||||
To install the debug adapter you may run =M-x dap-gdb-lldb-setup= when you are
|
||||
on Linux or download it manually from [[https://marketplace.visualstudio.com/items?itemName=webfreak.debug][Native Debug]] and adjust
|
||||
=dap-gdb-lldb-path=.
|
||||
|
||||
** Organize file header includes on save
|
||||
To organize the file header includes on save, set the layer variable
|
||||
=c++-enable-organize-includes-on-save= to =t= in the dotfile:
|
||||
|
@ -243,24 +266,12 @@ To organize the file header includes on save, set the layer variable
|
|||
'((c-c++ :variables c++-enable-organize-includes-on-save t)))
|
||||
#+END_SRC
|
||||
|
||||
** Clang Configuration
|
||||
To enable Clang support, set the layer variable =c-c++-enable-clang-support=
|
||||
to =t= in the dotfile:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq-default dotspacemacs-configuration-layers
|
||||
'((c-c++ :variables c-c++-enable-clang-support t)))
|
||||
#+END_SRC
|
||||
|
||||
N.B. do not set this option if either the =cquery= or =ccls= backend
|
||||
|
||||
*** clang-format
|
||||
** clang-format
|
||||
[[http://clang.llvm.org/docs/ClangFormat.html][clang-format]] allows reformatting either a selected region of code
|
||||
(=clang-format-region=) or a whole buffer (=clang-format-buffer=)
|
||||
according to a style defined in a =.clang-format= file. This file
|
||||
is either located in the same directory as the file being edited,
|
||||
or any of its parent directories. If no =.clang-format= is found,
|
||||
then a default style will be used.
|
||||
(=clang-format-region=) or a whole buffer (=clang-format-buffer=) according to a
|
||||
style defined in a =.clang-format= file. This file is either located in the same
|
||||
directory as the file being edited, or any of its parent directories. If no
|
||||
=.clang-format= is found, then a default style will be used.
|
||||
|
||||
To enable automatic buffer formatting on save, set the variable
|
||||
=c-c++-enable-clang-format-on-save= to =t=:
|
||||
|
@ -270,15 +281,6 @@ To enable automatic buffer formatting on save, set the variable
|
|||
'((c-c++ :variables c-c++-enable-clang-format-on-save t)))
|
||||
#+END_SRC
|
||||
|
||||
*** Company-clang and flycheck
|
||||
This layer adds some fancy improvements to =company-clang=. It includes a hook
|
||||
to load a projects =.clang_complete= file, which is just a text file with one
|
||||
clang flag per line, a format also used by other text editor clang plugins.
|
||||
|
||||
Not only does this allow proper autocomplete on projects with extra includes and
|
||||
flags, but there is also support for flycheck so that it doesn't complain about
|
||||
missing header files.
|
||||
|
||||
** Enable google-set-c-style
|
||||
If you have clang enabled with =clang-format= as described earlier in this page
|
||||
you may not have a lot of neeed for =google-set-c-style= if you are already
|
||||
|
@ -328,74 +330,22 @@ generally applicable.
|
|||
|
||||
* Key bindings
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+---------------------------------------------------------------|
|
||||
| ~SPC m g a~ | open matching file |
|
||||
| | (e.g. switch between .cpp and .h, requires a project to work) |
|
||||
| ~SPC m g A~ | open matching file in another window |
|
||||
| | (e.g. switch between .cpp and .h, requires a project to work) |
|
||||
| ~SPC m D~ | disaster: disassemble c/c++ code |
|
||||
| ~SPC m r .~ | srefactor: refactor thing at point. |
|
||||
| ~SPC m r i~ | organize includes |
|
||||
|
||||
*Note:* [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]] is only available for Emacs 24.4+.
|
||||
|
||||
** Formatting (clang-format)
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+---------------------------------|
|
||||
| ~SPC m = =~ | format current region or buffer |
|
||||
| ~SPC m = f~ | format current function |
|
||||
|
||||
** RTags
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+---------------------------------|
|
||||
| ~SPC m g .~ | find symbol at point |
|
||||
| ~SPC m g ,~ | find references at point |
|
||||
| ~SPC m g ;~ | find file |
|
||||
| ~SPC m g /~ | find all references at point |
|
||||
| ~SPC m g [~ | location stack back |
|
||||
| ~SPC m g ]~ | location stack forward |
|
||||
| ~SPC m g >~ | c++ tags find symbol |
|
||||
| ~SPC m g <~ | c++ tags find references |
|
||||
| ~SPC m g B~ | show rtags buffer |
|
||||
| ~SPC m g d~ | print dependencies |
|
||||
| ~SPC m g D~ | diagnostics |
|
||||
| ~SPC m g e~ | reparse file |
|
||||
| ~SPC m g E~ | preprocess file |
|
||||
| ~SPC m g F~ | fixit |
|
||||
| ~SPC m g G~ | guess function at point |
|
||||
| ~SPC m g h~ | print class hierarchy |
|
||||
| ~SPC m g I~ | c++ tags imenu |
|
||||
| ~SPC m g L~ | copy and print current location |
|
||||
| ~SPC m g M~ | symbol info |
|
||||
| ~SPC m g O~ | goto offset |
|
||||
| ~SPC m g p~ | set current project |
|
||||
| ~SPC m g R~ | rename symbol |
|
||||
| ~SPC m g s~ | print source arguments |
|
||||
| ~SPC m g S~ | display summary |
|
||||
| ~SPC m g T~ | taglist |
|
||||
| ~SPC m g v~ | find virtuals at point |
|
||||
| ~SPC m g V~ | print enum value at point |
|
||||
| ~SPC m g X~ | fix fixit at point |
|
||||
| ~SPC m g Y~ | cycle overlays on screen |
|
||||
|
||||
** LSP
|
||||
The default key bindings for LSP implementations are defined by/documented in the [[file:../../+tools/lsp/README.org][LSP layer]].
|
||||
The default key bindings for LSP implementations are defined by/documented in
|
||||
the [[file:../../+tools/lsp/README.org][LSP layer]].
|
||||
|
||||
** cquery / ccls
|
||||
*** cquery / ccls
|
||||
The key bindings listed below are in addition to
|
||||
A ~[ccls]~ or ~[cquery]~ suffix indicates that the binding is for the indicated backend only.
|
||||
|
||||
*** backend (language server)
|
||||
**** backend (language server)
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+------------------------------------------|
|
||||
| ~SPC m b f~ | refresh index (e.g. after branch change) |
|
||||
| ~SPC m b p~ | preprocess file |
|
||||
|
||||
*** goto
|
||||
**** goto
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+---------------------------|
|
||||
|
@ -428,7 +378,7 @@ A ~[ccls]~ or ~[cquery]~ suffix indicates that the binding is for the indicated
|
|||
| ~SPC m g m f~ | member functions [ccls] |
|
||||
| ~SPC m g m v~ | member variables [ccls] |
|
||||
|
||||
** debugger
|
||||
*** debugger
|
||||
|
||||
| Key binding | Description |
|
||||
|---------------+---------------------------------|
|
||||
|
@ -474,3 +424,68 @@ A ~[ccls]~ or ~[cquery]~ suffix indicates that the binding is for the indicated
|
|||
| ~SPC m d w o~ | goto output buffer if present |
|
||||
| ~SPC m d w s~ | list sessions |
|
||||
| ~SPC m d w b~ | list breakpoints |
|
||||
|
||||
** RTags
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+---------------------------------|
|
||||
| ~SPC m g .~ | find symbol at point |
|
||||
| ~SPC m g ,~ | find references at point |
|
||||
| ~SPC m g ;~ | find file |
|
||||
| ~SPC m g /~ | find all references at point |
|
||||
| ~SPC m g [~ | location stack back |
|
||||
| ~SPC m g ]~ | location stack forward |
|
||||
| ~SPC m g >~ | c++ tags find symbol |
|
||||
| ~SPC m g <~ | c++ tags find references |
|
||||
| ~SPC m g B~ | show rtags buffer |
|
||||
| ~SPC m g d~ | print dependencies |
|
||||
| ~SPC m g D~ | diagnostics |
|
||||
| ~SPC m g e~ | reparse file |
|
||||
| ~SPC m g E~ | preprocess file |
|
||||
| ~SPC m g F~ | fixit |
|
||||
| ~SPC m g G~ | guess function at point |
|
||||
| ~SPC m g h~ | print class hierarchy |
|
||||
| ~SPC m g I~ | c++ tags imenu |
|
||||
| ~SPC m g L~ | copy and print current location |
|
||||
| ~SPC m g M~ | symbol info |
|
||||
| ~SPC m g O~ | goto offset |
|
||||
| ~SPC m g p~ | set current project |
|
||||
| ~SPC m g R~ | rename symbol |
|
||||
| ~SPC m g s~ | print source arguments |
|
||||
| ~SPC m g S~ | display summary |
|
||||
| ~SPC m g T~ | taglist |
|
||||
| ~SPC m g v~ | find virtuals at point |
|
||||
| ~SPC m g V~ | print enum value at point |
|
||||
| ~SPC m g X~ | fix fixit at point |
|
||||
| ~SPC m g Y~ | cycle overlays on screen |
|
||||
|
||||
** Additional key-bindings
|
||||
*** Disassemble
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+----------------------------------|
|
||||
| ~SPC m D~ | disaster: disassemble c/c++ code |
|
||||
| | |
|
||||
|
||||
*** Formatting (clang-format)
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+---------------------------------|
|
||||
| ~SPC m = =~ | format current region or buffer |
|
||||
| ~SPC m = f~ | format current function |
|
||||
|
||||
*** Open matching files
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+---------------------------------------------------------------|
|
||||
| ~SPC m g a~ | open matching file |
|
||||
| | (e.g. switch between .cpp and .h, requires a project to work) |
|
||||
| ~SPC m g A~ | open matching file in another window |
|
||||
| | (e.g. switch between .cpp and .h, requires a project to work) |
|
||||
|
||||
*** Refactor
|
||||
|
||||
| Key binding | Description |
|
||||
|-------------+-------------------------------------|
|
||||
| ~SPC m r .~ | srefactor: refactor thing at point. |
|
||||
| ~SPC m r i~ | organize includes |
|
||||
|
|
|
@ -15,49 +15,34 @@
|
|||
(spacemacs|define-jump-handlers c-mode)
|
||||
|
||||
(defvar c-c++-backend nil
|
||||
"May be `nil', `rtags' or `lsp'.")
|
||||
|
||||
(defconst c-c++-lsp-backends '(lsp-cquery lsp-ccls)
|
||||
"Language Server Protocol (LSP) backends supported by the `c-c++' layer.")
|
||||
"The backend to use for IDE features.
|
||||
Possible values are `lsp-ccls', `lsp-cquery', `lsp-clangd', `rtags' and `ycmd'.")
|
||||
|
||||
|
||||
;; lsp
|
||||
|
||||
(defconst c-c++-lsp-servers '(clangd ccls cquery)
|
||||
"Language Server Protocol (LSP) backends supported by the `c-c++' layer.")
|
||||
|
||||
(defvar c-c++-lsp-server 'clangd
|
||||
"May be any member of `c-c++-lsp-servers'")
|
||||
|
||||
(defvar c-c++-lsp-cache-dir nil
|
||||
"Cache directory. Absolute and relative paths supported.")
|
||||
"Cache directory for lsp backends.
|
||||
Can be nil, an absolute path or a relative path.
|
||||
If it is nil then the cache directory is in `spacemacs-cache-directory'.
|
||||
If it is a relative path then it is relative to the project root.
|
||||
|
||||
(defvar c-c++-lsp-executable nil
|
||||
"Path to cquery/ccls executable (default value assumes it's in the path)")
|
||||
Notes:
|
||||
- The name of the selected LSP backend is automatically appended to this
|
||||
path.
|
||||
- This variable has no effect with `lsp-clangd' backend.")
|
||||
|
||||
(defvar c-c++-lsp-project-whitelist nil
|
||||
"A list of project directory patterns for which lsp-c-c++ should be
|
||||
initialized. This overrides `c-c++-lsp-project-blacklist'.")
|
||||
(defvar c-c++-lsp-enable-semantic-highlight nil
|
||||
"If non-nil then enable semantic highlighting.
|
||||
If `t' then regular semantic highlighting is enabled.
|
||||
If `rainbow' then rainbow semantic highlighting is enabled.
|
||||
Rainbow semantic highlighting gives a unique color to each identifier.")
|
||||
|
||||
(defvar c-c++-lsp-project-blacklist nil
|
||||
"A list of project root patterns for which lsp-c-c++ shouldn't be
|
||||
initialized. `c-c++-lsp-project-whitelist' is checked first, then this,
|
||||
if no pattern matches the project root, lsp-c-c++ will be initialized.")
|
||||
(defvar c-c++-lsp-semantic-highlight-method 'font-lock
|
||||
"Method used to highlight the text when semantic highlighting is enabled.
|
||||
|
||||
(defvar c-c++-lsp-sem-highlight-method nil
|
||||
"Set to 'font-lock or 'overlay to enable semantic highlighting")
|
||||
|
||||
(defvar c-c++-lsp-sem-highlight-rainbow nil
|
||||
"When non-nil, use rainbow semantic highlighting")
|
||||
|
||||
(defvar c-c++-lsp-initialization-options nil
|
||||
"Extra initialisation parameters to pass to the lsp backend. See
|
||||
https://github.com/MaskRay/ccls/blob/master/src/config.hh
|
||||
for details. N.B. This is remapped to cquery-extra-init-params when using cquery backend")
|
||||
|
||||
(defvar c-c++-lsp-args nil
|
||||
"Extra args to pass to the backend. E.g. to log to file.
|
||||
https://github.com/MaskRay/ccls/wiki/Emacs for details. N.B. this is remapped to cquery-extra-args when using cquery backend")
|
||||
By default `font-lock' is used to highlight the text, set the variable to
|
||||
`overlay' if you want to use overlays. Note that overlays can be slower.")
|
||||
|
||||
|
||||
;; rtags
|
||||
|
@ -68,9 +53,6 @@ https://github.com/MaskRay/ccls/wiki/Emacs for details. N.B. this is remapped to
|
|||
|
||||
;; clang
|
||||
|
||||
(defvar c-c++-enable-clang-support nil
|
||||
"If non nil Clang related packages and configuration are enabled.")
|
||||
|
||||
(defvar c-c++-enable-clang-format-on-save nil
|
||||
"If non-nil, automatically format code with ClangFormat on
|
||||
save. Clang support has to be enabled for this to work.")
|
||||
|
|
|
@ -12,152 +12,332 @@
|
|||
(require 'cl-lib)
|
||||
(require 'subr-x)
|
||||
|
||||
(defun spacemacs//c-toggle-auto-newline ()
|
||||
"Toggle auto-newline."
|
||||
(c-toggle-auto-newline 1))
|
||||
(defun spacemacs//c-c++-backend ()
|
||||
"Returns selected backend."
|
||||
(if c-c++-backend
|
||||
c-c++-backend
|
||||
(cond
|
||||
((configuration-layer/layer-used-p 'lsp) 'lsp-clangd)
|
||||
(t nil))))
|
||||
|
||||
(defun spacemacs//c-c++-setup-backend ()
|
||||
"Conditionally setup c-c++ backend."
|
||||
(pcase (spacemacs//c-c++-backend)
|
||||
(`lsp-clangd (spacemacs//c-c++-setup-lsp-clangd))
|
||||
(`lsp-ccls (spacemacs//c-c++-setup-lsp-ccls))
|
||||
(`lsp-cquery (spacemacs//c-c++-setup-lsp-cquery))
|
||||
(`rtags (spacemacs//c-c++-setup-rtags))
|
||||
(`ycmd (spacemacs//c-c++-setup-ycmd))))
|
||||
|
||||
(defun spacemacs//c-c++-setup-company ()
|
||||
"Conditionally setup C/C++ company integration based on backend."
|
||||
(pcase (spacemacs//c-c++-backend)
|
||||
(`lsp-clangd (spacemacs//c-c++-setup-lsp-company))
|
||||
(`lsp-ccls (spacemacs//c-c++-setup-lsp-company))
|
||||
(`lsp-cquery (spacemacs//c-c++-setup-lsp-company))
|
||||
(`rtags (spacemacs//c-c++-setup-rtags-company))
|
||||
(`ycmd (spacemacs//c-c++-setup-ycmd-company))))
|
||||
|
||||
(defun spacemacs//c-c++-setup-dap ()
|
||||
"Conditionally setup C/C++ DAP integration based on backend."
|
||||
;; currently DAP is only available using LSP
|
||||
(pcase (spacemacs//c-c++-backend)
|
||||
(`lsp-clangd (spacemacs//c-c++-setup-lsp-dap))
|
||||
(`lsp-ccls (spacemacs//c-c++-setup-lsp-dap))
|
||||
(`lsp-cquery (spacemacs//c-c++-setup-lsp-dap))))
|
||||
|
||||
(defun spacemacs//c-c++-setup-eldoc ()
|
||||
"Conditionally setup C/C++ eldoc integration based on backend."
|
||||
(pcase (spacemacs//c-c++-backend)
|
||||
;; lsp setup eldoc on its own
|
||||
(`ycmd (spacemacs//c-c++-setup-ycmd-eldoc))))
|
||||
|
||||
(defun spacemacs//c-c++-setup-flycheck ()
|
||||
"Conditionally setup C/C++ flycheck integration based on backend."
|
||||
(pcase (spacemacs//c-c++-backend)
|
||||
(`lsp-clangd (spacemacs//c-c++-setup-lsp-flycheck))
|
||||
(`lsp-ccls (spacemacs//c-c++-setup-lsp-flycheck))
|
||||
(`lsp-cquery (spacemacs//c-c++-setup-lsp-flycheck))
|
||||
(`rtags (spacemacs//c-c++-setup-rtags-flycheck))
|
||||
(`ycmd (spacemacs//c-c++-setup-ycmd-flycheck))))
|
||||
|
||||
(defun spacemacs//c-c++-setup-format ()
|
||||
"Conditionally setup format based on backend."
|
||||
(pcase (spacemacs//c-c++-backend)
|
||||
(`lsp-clangd (spacemacs//c-c++-setup-clang-format))
|
||||
(`lsp-ccls (spacemacs//c-c++-setup-clang-format))
|
||||
(`lsp-cquery (spacemacs//c-c++-setup-clang-format))))
|
||||
|
||||
|
||||
;; lsp
|
||||
|
||||
;; clang
|
||||
|
||||
(defun spacemacs/clang-format-function (&optional style)
|
||||
"Format the current function with clang-format according to STYLE."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(c-mark-function)
|
||||
(clang-format (region-beginning) (region-end) style)
|
||||
(deactivate-mark) ; If the function is already formatted, then remove the mark
|
||||
(message "Formatted function %s" (c-defun-name))))
|
||||
(defun spacemacs//c-c++-setup-lsp-clangd ()
|
||||
"Setup LSP clangd."
|
||||
;; extensions
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-clangd"
|
||||
'clangd-other-file "textDocument/switchSourceHeader" 'buffer-file-name)
|
||||
(lsp))
|
||||
|
||||
(defun spacemacs/clang-format-region-or-buffer (&optional style)
|
||||
"Format the current region or buffer with clang-format according to STYLE."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(if (region-active-p)
|
||||
(progn
|
||||
(clang-format-region (region-beginning) (region-end) style)
|
||||
(message "Formatted region"))
|
||||
(progn
|
||||
(clang-format-buffer style)
|
||||
(message "Formatted buffer %s" (buffer-name))))))
|
||||
;; ccls
|
||||
|
||||
(defun spacemacs//clang-format-on-save ()
|
||||
"Format the current buffer with clang-format on save when
|
||||
`c-c++-enable-clang-format-on-save' is non-nil."
|
||||
(when c-c++-enable-clang-format-on-save
|
||||
(spacemacs/clang-format-region-or-buffer)))
|
||||
(defun spacemacs//c-c++-setup-lsp-ccls ()
|
||||
"Setup LSP ccls."
|
||||
(require 'ccls)
|
||||
;; configuration
|
||||
(let ((cache-dir
|
||||
(if (null c-c++-lsp-cache-dir)
|
||||
(concat spacemacs-cache-directory "lsp-ccls")
|
||||
(concat (file-truename (file-name-as-directory c-c++-lsp-cache-dir))
|
||||
"lsp-ccls"))))
|
||||
(append ccls-initialization-options
|
||||
`(:cache (:directory ,cache-dir))))
|
||||
|
||||
(defun spacemacs/clang-format-on-save ()
|
||||
"Add before-save hook for clang-format."
|
||||
(add-hook 'before-save-hook 'spacemacs//clang-format-on-save nil t))
|
||||
;; semantic highlight
|
||||
(when c-c++-lsp-enable-semantic-highlight
|
||||
(setq ccls-sem-highlight-method c-c++-lsp-semantic-highlight-method)
|
||||
(when (eq 'rainbow c-c++-lsp-enable-semantic-highlight)
|
||||
(ccls-use-default-rainbow-sem-highlight)))
|
||||
|
||||
(defun spacemacs/company-more-than-prefix-guesser ()
|
||||
(spacemacs/c-c++-load-clang-args)
|
||||
(company-clang-guess-prefix))
|
||||
;; extensions
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'refs-address "textDocument/references" '(:role 128))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'refs-read "textDocument/references" '(:role 8))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'refs-write "textDocument/references" '(:role 16))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'callers "$ccls/call")
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'callees "$ccls/call" '(:callee t))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'base "$ccls/inheritance")
|
||||
;;ccls features without a cquery analogue...
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'derived "$ccls/inheritance" '(:derived t))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'member-types "$ccls/member" `(:kind 2))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'member-functions "$ccls/member" `(:kind 3))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-ccls"
|
||||
'member-vars "$ccls/member" `(:kind 0))
|
||||
|
||||
;; Based on the Sarcasm/irony-mode compilation database code.
|
||||
(defun spacemacs/company-find-clang-complete-file ()
|
||||
(when buffer-file-name
|
||||
(let ((dir (locate-dominating-file buffer-file-name ".clang_complete")))
|
||||
(when dir
|
||||
(concat (file-name-as-directory dir) ".clang_complete")))))
|
||||
;; key bindings
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
;; backend
|
||||
"bf" 'ccls-reload
|
||||
"bp" 'ccls-preprocess-file
|
||||
;; goto
|
||||
"gf" 'find-file-at-point
|
||||
"gF" 'ffap-other-window
|
||||
;; hierarchy
|
||||
"ghc" 'ccls-call-hierarchy
|
||||
"ghC" 'spacemacs/c-c++-lsp-ccls-call-hierarchy-inv
|
||||
"ghi" 'ccls-inheritance-hierarchy
|
||||
"ghI" 'spacemacs/c-c++-lsp-ccls-inheritance-hierarchy-inv
|
||||
;; members
|
||||
"gmh" 'ccls-member-hierarchy)
|
||||
|
||||
;; Based on the Sarcasm/irony-mode compilation database code.
|
||||
(defun spacemacs/company-load-clang-complete-file (cc-file)
|
||||
"Load the flags from CC-FILE, one flag per line."
|
||||
(let ((invocation-dir (expand-file-name (file-name-directory cc-file)))
|
||||
(case-fold-search nil)
|
||||
(include-regex "\\(-I\\|-isystem\\|-iquote\\|-idirafter\\)\\s-*\\(\\S-+\\)")
|
||||
compile-flags)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents cc-file)
|
||||
;; Replace relative paths with absolute paths (by @trishume)
|
||||
;; (goto-char (point-min))
|
||||
(while (re-search-forward include-regex nil t)
|
||||
(replace-match (format "%s%s" (match-string 1)
|
||||
(expand-file-name (match-string 2)
|
||||
invocation-dir))))
|
||||
;; Turn lines into a list
|
||||
(setq compile-flags
|
||||
;; remove whitespaces at the end of each line, if any
|
||||
(mapcar #'(lambda (line)
|
||||
(if (string-match "[ \t]+$" line)
|
||||
(replace-match "" t t line)
|
||||
line))
|
||||
(split-string (buffer-string) "\n" t))))
|
||||
compile-flags))
|
||||
;;Replace this with lsp-goto-implementation in lsp-layer?
|
||||
(spacemacs/lsp-bind-extensions-for-mode
|
||||
mode "c-c++" "lsp-ccls"
|
||||
"&" 'refs-address
|
||||
"R" 'refs-read
|
||||
"W" 'refs-write
|
||||
"c" 'callers
|
||||
"C" 'callees
|
||||
"v" 'vars
|
||||
"hb" 'base)
|
||||
|
||||
(defun spacemacs//c-c++-get-standard-include-paths (lang)
|
||||
"Returns the default system header include paths for LANG if gcc is on the
|
||||
system and supports it, else returns a default set of include paths."
|
||||
(let* ((start "#include <...> search starts here:")
|
||||
(end "End of search list.")
|
||||
(gcc-tmplt "echo | gcc -x%s -E -v - 2>&1")
|
||||
(sed-tmplt " | sed -n '/%s/,/%s/{/%s/b;/%s/b;p}' | sed -e 's/^ *//g'")
|
||||
(template (concat gcc-tmplt sed-tmplt))
|
||||
(inc-dirs-cmd (format template lang start end start end))
|
||||
(inc-dirs (split-string (shell-command-to-string inc-dirs-cmd)
|
||||
"\n" t)))
|
||||
(if (and inc-dirs (every 'file-exists-p inc-dirs))
|
||||
inc-dirs
|
||||
'("/usr/include" "/usr/local/include"))))
|
||||
(spacemacs/lsp-bind-extensions-for-mode
|
||||
mode "c-c++" "lsp-ccls"
|
||||
"hd" 'derived
|
||||
"mt" 'member-types
|
||||
"mf" 'member-functions
|
||||
"mv" 'member-vars))
|
||||
|
||||
(defun spacemacs//filter-and-substring (flags filter-prefix substr-index)
|
||||
"Returns all the strings in FLAGS starting with FILTER-PREFIX. The returned
|
||||
strings are substringed from SUBSTR-INDEX inclusive to the end of the string."
|
||||
(mapcar (lambda (f) (substring f substr-index))
|
||||
(remove-if-not (lambda (f) (string-prefix-p filter-prefix f))
|
||||
flags)))
|
||||
;;(evil-set-initial-state 'ccls--tree-mode 'emacs)
|
||||
;;evil-record-macro keybinding clobbers q in cquery-tree-mode-map for some reason?
|
||||
;;(evil-make-overriding-map 'ccls-tree-mode-map)
|
||||
(lsp))
|
||||
|
||||
(defun spacemacs/c-c++-load-clang-args ()
|
||||
"Sets the arguments for company-clang, the system paths for company-c-headers
|
||||
and the arguments for flyckeck-clang based on a project-specific text file."
|
||||
(unless company-clang-arguments
|
||||
(let* ((cc-file (spacemacs/company-find-clang-complete-file))
|
||||
(flags (if cc-file
|
||||
(spacemacs/company-load-clang-complete-file cc-file)
|
||||
'()))
|
||||
(i-paths (spacemacs//filter-and-substring flags
|
||||
"-I" 2))
|
||||
(iquote-paths (spacemacs//filter-and-substring flags
|
||||
"-iquote" 7))
|
||||
(isystem-paths (spacemacs//filter-and-substring flags
|
||||
"-isystem" 8))
|
||||
(idirafter-paths (spacemacs//filter-and-substring flags
|
||||
"-idirafter" 10)))
|
||||
(setq-local company-clang-arguments flags)
|
||||
(setq-local flycheck-clang-args flags)
|
||||
(setq-local company-c-headers-path-user
|
||||
(append '(".")
|
||||
iquote-paths))
|
||||
(setq-local company-c-headers-path-system
|
||||
(append i-paths
|
||||
isystem-paths
|
||||
(when (string-equal major-mode "c++-mode")
|
||||
(spacemacs//c-c++-get-standard-include-paths "c++"))
|
||||
(when (string-equal major-mode "c-mode")
|
||||
(spacemacs//c-c++-get-standard-include-paths "c"))
|
||||
idirafter-paths)))))
|
||||
;; cquery
|
||||
|
||||
|
||||
;; cpp-auto-include
|
||||
(defun spacemacs//c-c++-setup-lsp-cquery ()
|
||||
"Setup LSP cquery."
|
||||
(require 'cquery)
|
||||
;; configuration
|
||||
(setq cquery-cache-dir
|
||||
(if (null c-c++-lsp-cache-dir)
|
||||
(concat spacemacs-cache-directory "lsp-cquery")
|
||||
(concat (file-truename (file-name-as-directory c-c++-lsp-cache-dir))
|
||||
"lsp-cquery")))
|
||||
|
||||
(defalias 'spacemacs/c++-organize-includes 'cpp-auto-include)
|
||||
;; semantic highlight
|
||||
(when c-c++-lsp-enable-semantic-highlight
|
||||
(setq cquery-sem-highlight-method c-c++-lsp-semantic-highlight-method)
|
||||
(when (eq 'rainbow c-c++-lsp-enable-semantic-highlight)
|
||||
(cquery-use-default-rainbow-sem-highlight)))
|
||||
|
||||
(defun spacemacs//c++-organize-includes-on-save ()
|
||||
"Organize the includes on save when `c++-enable-organize-includes-on-save'
|
||||
is non-nil."
|
||||
(when c++-enable-organize-includes-on-save
|
||||
(spacemacs/c++-organize-includes)))
|
||||
;; extensions
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-cquery"
|
||||
'refs-address "textDocument/references"
|
||||
'(plist-put (lsp--text-document-position-params) :context '(:role 128)))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-cquery"
|
||||
'refs-read "textDocument/references"
|
||||
'(plist-put (lsp--text-document-position-params) :context '(:role 8)))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-cquery"
|
||||
'refs-write "textDocument/references"
|
||||
'(plist-put (lsp--text-document-position-params) :context '(:role 16)))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-cquery"
|
||||
'callers "$cquery/callers")
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-cquery"
|
||||
'callees "$cquery/callers" '(:callee t))
|
||||
(spacemacs/lsp-define-extensions
|
||||
"c-c++" "lsp-cquery"
|
||||
'base "$cquery/base")
|
||||
|
||||
(defun spacemacs/c++-organize-includes-on-save ()
|
||||
"Add before-save hook for c++-organize-includes."
|
||||
(add-hook 'before-save-hook
|
||||
#'spacemacs//c++-organize-includes-on-save nil t))
|
||||
;; key bindings
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
;; backend
|
||||
"bf" 'cquery-freshen-index
|
||||
"bp" 'cquery-preprocess-file
|
||||
;; goto
|
||||
"gf" 'find-file-at-point
|
||||
"gF" 'ffap-other-window
|
||||
;; hierarchy
|
||||
"ghc" 'cquery-call-hierarchy
|
||||
"ghC" 'spacemacs/c-c++-lsp-cquery-call-hierarchy-inv
|
||||
"ghi" 'cquery-inheritance-hierarchy
|
||||
"ghI" 'spacemacs/c-c++-lsp-cquery-inheritance-hierarchy-inv
|
||||
;; members
|
||||
"gmh" 'cquery-member-hierarchy)
|
||||
|
||||
;;Replace this with lsp-goto-implementation in lsp-layer?
|
||||
(spacemacs/lsp-bind-extensions-for-mode
|
||||
mode "c-c++" "lsp-cquery"
|
||||
"&" 'refs-address
|
||||
"R" 'refs-read
|
||||
"W" 'refs-write
|
||||
"c" 'callers
|
||||
"C" 'callees
|
||||
"v" 'vars
|
||||
"hb" 'base))
|
||||
|
||||
;;(evil-set-initial-state 'ccls--tree-mode 'emacs)
|
||||
;;evil-record-macro keybinding clobbers q in cquery-tree-mode-map for some reason?
|
||||
;;(evil-make-overriding-map 'ccls-tree-mode-map)
|
||||
(lsp))
|
||||
|
||||
(defun spacemacs//c-c++-setup-lsp-company ()
|
||||
"Setup lsp auto-completion."
|
||||
(spacemacs|add-company-backends
|
||||
:backends company-lsp
|
||||
:modes c-mode c++-mode
|
||||
:append-hooks nil
|
||||
:call-hooks t)
|
||||
(company-mode))
|
||||
|
||||
(defun spacemacs//c-c++-setup-lsp-dap ()
|
||||
"Setup DAP integration."
|
||||
(require 'dap-gdb-lldb))
|
||||
|
||||
|
||||
(defun spacemacs//c-c++-setup-lsp-flycheck ()
|
||||
"Setup LSP syntax checking."
|
||||
(when (or (spacemacs/enable-flycheck 'c-mode)
|
||||
(spacemacs/enable-flycheck 'c++-mode))
|
||||
(require 'lsp-ui-flycheck)
|
||||
(lsp-ui-flycheck-enable nil)
|
||||
(flycheck-mode)))
|
||||
|
||||
|
||||
;; rtags
|
||||
|
||||
(defun spacemacs//c-c++-setup-rtags ()
|
||||
"Setup rtags backend."
|
||||
(setq rtags-autostart-diagnostics t)
|
||||
(add-hook 'rtags-jump-hook 'evil-set-jump)
|
||||
(rtags-diagnostics)
|
||||
;; key bindings
|
||||
(evil-define-key 'normal rtags-mode-map
|
||||
(kbd "RET") 'rtags-select-other-window
|
||||
(kbd "M-RET") 'rtags-select
|
||||
(kbd "q") 'rtags-bury-or-delete)
|
||||
;; TODO check for consistency with gtags key bindings
|
||||
;; see https://github.com/syl20bnr/spacemacs/blob/develop/layers/+tags/gtags/funcs.el#L70
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
"g." 'spacemacs/c-c++-tags-find-symbol-at-point
|
||||
"g," 'spacemacs/c-c++-tags-find-references-at-point
|
||||
"g;" 'spacemacs/c-c++-tags-find-file
|
||||
"g/" 'rtags-find-all-references-at-point
|
||||
"g[" 'rtags-location-stack-back
|
||||
"g]" 'rtags-location-stack-forward
|
||||
"g>" 'spacemacs/c-c++-tags-find-symbol
|
||||
"g<" 'spacemacs/c-c++-tags-find-references
|
||||
"gB" 'rtags-show-rtags-buffer
|
||||
"gd" 'rtags-print-dependencies
|
||||
"gD" 'rtags-diagnostics
|
||||
"ge" 'rtags-reparse-file
|
||||
"gE" 'rtags-preprocess-file
|
||||
"gF" 'rtags-fixit
|
||||
"gG" 'rtags-guess-function-at-point
|
||||
"gh" 'rtags-print-class-hierarchy
|
||||
"gI" 'spacemacs/c-c++-tags-imenu
|
||||
"gL" 'rtags-copy-and-print-current-location
|
||||
"gM" 'rtags-symbol-info
|
||||
"gO" 'rtags-goto-offset
|
||||
"gp" 'rtags-set-current-project
|
||||
"gR" 'rtags-rename-symbol
|
||||
"gs" 'rtags-print-source-arguments
|
||||
"gS" 'rtags-display-summary
|
||||
"gT" 'rtags-taglist
|
||||
"gv" 'rtags-find-virtuals-at-point
|
||||
"gV" 'rtags-print-enum-value-at-point
|
||||
"gX" 'rtags-fix-fixit-at-point
|
||||
"gY" 'rtags-cycle-through-diagnostics)))
|
||||
|
||||
(defun spacemacs//c-c++-setup-rtags-company ()
|
||||
"Setup rtags auto-completion."
|
||||
(setq rtags-completions-enabled t)
|
||||
(spacemacs|add-company-backends
|
||||
:backends company-rtags
|
||||
:modes c-mode-common
|
||||
:append-hooks nil
|
||||
:call-hooks t))
|
||||
|
||||
(defun spacemacs//c-c++-setup-rtags-flycheck ()
|
||||
"Setup rtags syntax checking."
|
||||
(when (or (spacemacs/enable-flycheck 'c-mode)
|
||||
(spacemacs/enable-flycheck 'c++-mode))
|
||||
(require 'flycheck-rtags)
|
||||
(flycheck-mode)))
|
||||
|
||||
(defun spacemacs//c-c++-setup-rtags-semantic ()
|
||||
"Setup semantic for rtags."
|
||||
(semantic-mode)
|
||||
(spacemacs//disable-semantic-idle-summary-mode))
|
||||
|
||||
(defun spacemacs/c-c++-use-rtags (&optional useFileManager)
|
||||
"Return non-nil if rtags function should be used."
|
||||
;; this function is used to fallback on gtags function if rtags is not
|
||||
|
@ -204,192 +384,126 @@ is non-nil."
|
|||
'rtags-imenu 'idomenu)))
|
||||
|
||||
|
||||
;; lsp
|
||||
;; -- BEGIN helper functions for common configuration of cquery and ccls backends
|
||||
(defun spacemacs//c-c++-lsp-string (prefix suffix)
|
||||
(concat prefix (symbol-name c-c++-lsp-server) suffix))
|
||||
;; ycmd
|
||||
|
||||
(defun spacemacs//c-c++-lsp-symbol (prefix suffix)
|
||||
"Return a symbol for the LSP server specified by the `c-c++-lsp-server' configuration variable."
|
||||
(intern (spacemacs//c-c++-lsp-string prefix suffix)))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-call-function (prefix suffix &rest args)
|
||||
(apply (spacemacs//c-c++-lsp-symbol prefix suffix) args))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-funcall-interactively (prefix suffix &rest args)
|
||||
(funcall-interactively (spacemacs//c-c++-lsp-symbol prefix suffix) args))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-funcall-interactively-no-args (prefix suffix)
|
||||
(funcall-interactively (spacemacs//c-c++-lsp-symbol prefix suffix)))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-set-symbol (prefix suffix value)
|
||||
(set (spacemacs//c-c++-lsp-symbol prefix suffix) (symbol-value value)))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-set-config (param prefix suffix)
|
||||
(when (symbol-value param) (spacemacs//c-c++-lsp-set-symbol prefix suffix param)))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-apply-config (&rest parameters)
|
||||
"Configure ccls or cquery (both take similarly named configuration parameters)."
|
||||
(dolist (suffix parameters) (spacemacs//c-c++-lsp-set-config (intern (concat "c-c++-lsp-" suffix)) nil (concat "-" suffix))))
|
||||
;; -- END helper functions for common configuration of cquery and ccls backends
|
||||
|
||||
(defun spacemacs//c-c++-lsp-apply-clangd-config ()
|
||||
"Configure clangd."
|
||||
(when c-c++-lsp-executable (setq lsp-clients-clangd-executable c-c++-lsp-executable))
|
||||
(when c-c++-lsp-args (setq lsp-clients-clangd-args c-c++-lsp-args)))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-config ()
|
||||
"Configure the LSP server specified by the `c-c++-lsp-server' configuration variable."
|
||||
(progn
|
||||
(message "Configuring c-c++ lsp backend")
|
||||
(spacemacs//c-c++-lsp-define-extensions)
|
||||
(if (eq c-c++-lsp-server 'clangd)
|
||||
(spacemacs//c-c++-lsp-apply-clangd-config)
|
||||
(spacemacs//c-c++-lsp-wrap-functions)
|
||||
(spacemacs//c-c++-lsp-apply-config "executable" "initialization-options" "args" "project-whitelist" "project-blacklist" "sem-highlight-method"))
|
||||
;; TODO Do we still want to disable c/c++-clang if using clangd as lsp-server?
|
||||
(setq-default flycheck-disabled-checkers '(c/c++-clang c/c++-gcc))
|
||||
|
||||
(if (eq c-c++-lsp-cache-dir nil)
|
||||
(progn
|
||||
(setq c-c++-lsp-cache-dir (file-truename(concat "~/.emacs.d/.cache/" (symbol-name c-c++-lsp-server))))
|
||||
(message (concat "c-c++: No c-c++-lsp-cache-dir specified: defaulting to " c-c++-lsp-cache-dir))))
|
||||
|
||||
(ecase c-c++-lsp-server
|
||||
('clangd nil)
|
||||
('cquery (setq cquery-cache-dir c-c++-lsp-cache-dir)
|
||||
(setq cquery-extra-args c-c++-lsp-args)
|
||||
(setq cquery-extra-init-params
|
||||
(if c-c++-lsp-initialization-options
|
||||
(append c-c++-lsp-initialization-options '(:cacheFormat "msgpack"))
|
||||
'(:cacheFormat "msgpack"))))
|
||||
('ccls (setq ccls-initialization-options
|
||||
(if c-c++-lsp-initialization-options
|
||||
(append c-c++-lsp-initialization-options `(:cache (:directory ,c-c++-lsp-cache-dir)))
|
||||
`(:cache (:directory ,c-c++-lsp-cache-dir ))))))
|
||||
|
||||
(when c-c++-lsp-sem-highlight-rainbow
|
||||
(unless c-c++-lsp-sem-highlight-method
|
||||
(progn
|
||||
(setq c-c++-lsp-sem-highlight-method 'font-lock)
|
||||
(message "c-c++: No semantic highlight method specified. Defaulting to `font-lock'.")))
|
||||
;; This doesn't work, as can't apply (apply ...) to a macro...
|
||||
;; (unless (eq c-c++-lsp-server 'clangd)
|
||||
;; (spacemacs//c-c++-lsp-call-function nil "-use-default-rainbow-sem-highlight"))
|
||||
(ecase c-c++-lsp-server
|
||||
('clangd nil)
|
||||
('cquery (cquery-use-default-rainbow-sem-highlight))
|
||||
('ccls (ccls-use-default-rainbow-sem-highlight))))
|
||||
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs//c-c++-lsp-bind-keys-for-mode mode))
|
||||
|
||||
(unless (eq c-c++-lsp-server 'clangd)
|
||||
(evil-set-initial-state '(spacemacs//c-c++-lsp-symbol nil "-tree-mode") 'emacs)
|
||||
;;evil-record-macro keybinding clobbers q in cquery-tree-mode-map for some reason?
|
||||
(evil-make-overriding-map (symbol-value (spacemacs//c-c++-lsp-symbol nil "-tree-mode-map"))))
|
||||
|
||||
;; DAP layer now declared as a dependency in layers.el
|
||||
(require 'dap-gdb-lldb)))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-wrap-functions ()
|
||||
"Wrap navigation functions for the LSP server specified by the `c-c++-lsp-server' configuration variable.
|
||||
This is only valid for 'ccls or 'cquery."
|
||||
(defun c-c++/call-hierarchy () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-call-hierarchy"))
|
||||
(defun c-c++/call-hierarchy-inv () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-call-hierarchy" t))
|
||||
(defun c-c++/inheritance-hierarchy () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-inheritance-hierarchy"))
|
||||
(defun c-c++/inheritance-hierarchy-inv () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-inheritance-hierarchy" t))
|
||||
(defun c-c++/member-hierarchy () (interactive) (spacemacs//c-c++-lsp-funcall-interactively-no-args nil "-member-hierarchy"))
|
||||
(defun c-c++/preprocess-file () (interactive) (spacemacs//c-c++-lsp-funcall-interactively nil "-preprocess-file"))
|
||||
(defun c-c++/refresh-index () (interactive) ()
|
||||
(ecase c-c++-lsp-server
|
||||
('clangd nil)
|
||||
('cquery (cquery-freshen-index))
|
||||
('ccls (ccls-reload)))))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-bind-keys-for-mode (mode)
|
||||
"Bind LSP backend functions for the specified mode."
|
||||
(message "Binding keys for mode `%s'" mode)
|
||||
;; Don't bind this -- redundant, and the current wrapper doesn't work -- not invoking correctly
|
||||
;; (if (eq c-c++-lsp-server 'clangd)
|
||||
;; (spacemacs/lsp-bind-extensions-for-mode mode "c-c++"
|
||||
;; "o" 'clangd-other-file)
|
||||
(unless (eq c-c++-lsp-server 'clangd)
|
||||
(defun spacemacs//c-c++-setup-ycmd ()
|
||||
"Setup ycmd backend."
|
||||
(add-to-list 'spacemacs-jump-handlers-c++-mode '(ycmd-goto :async t))
|
||||
(add-to-list 'spacemacs-jump-handlers-c-mode '(ycmd-goto :async t))
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
;; backend
|
||||
"bf" #'c-c++/refresh-index
|
||||
"bp" #'c-c++/preprocess-file
|
||||
;; goto
|
||||
"gf" 'find-file-at-point
|
||||
"gF" 'ffap-other-window
|
||||
;; hierarchy
|
||||
"ghc" #'c-c++/call-hierarchy
|
||||
"ghC" #'c-c++/call-hierarchy-inv
|
||||
"ghi" #'c-c++/inheritance-hierarchy
|
||||
"ghI" #'c-c++/inheritance-hierarchy-inv
|
||||
;; members
|
||||
"gmh" #'c-c++/member-hierarchy)
|
||||
"gG" 'ycmd-goto-imprecise))
|
||||
(ycmd-mode))
|
||||
|
||||
;; goto/peek
|
||||
(spacemacs/lsp-bind-extensions-for-mode mode "c-c++"
|
||||
"&" 'refs-address
|
||||
"R" 'refs-read
|
||||
"W" 'refs-write
|
||||
"c" 'callers
|
||||
"C" 'callees
|
||||
"v" 'vars
|
||||
"hb" 'base) ;;Replace this with lsp-goto-implementation in lsp-layer?
|
||||
)
|
||||
(when (eq c-c++-backend 'ccls)
|
||||
(spacemacs/lsp-bind-extensions-for-mode mode "c-c++"
|
||||
"hd" 'derived
|
||||
"mt" 'member-types
|
||||
"mf" 'member-functions
|
||||
"mv" 'member-vars)))
|
||||
(defun spacemacs//c-c++-setup-ycmd-company ()
|
||||
"Setup ycmd auto-completion."
|
||||
(spacemacs|add-company-backends
|
||||
:backends company-ycmd
|
||||
:modes c-mode-common
|
||||
:append-hooks nil
|
||||
:call-hooks t))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-define-extensions ()
|
||||
"Wrap some backend-specific extensions using the find functions provided by lsp-mode and lsp-ui"
|
||||
(spacemacs//c-c++-lsp-call-function "spacemacs//c-c++-lsp-define-" "-extensions")
|
||||
(defun spacemacs//c-c++-setup-ycmd-eldoc ()
|
||||
"Setup ycmd eldoc integration."
|
||||
(ycmd-eldoc-setup))
|
||||
|
||||
(unless (eq c-c++-lsp-server 'clangd)
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'vars (spacemacs//c-c++-lsp-string "$" "/vars"))))
|
||||
(defun spacemacs//c-c++-setup-ycmd-flycheck ()
|
||||
"Setup ycmd syntax checking."
|
||||
(when (or (spacemacs/enable-flycheck 'c-mode)
|
||||
(spacemacs/enable-flycheck 'c++-mode))
|
||||
(flycheck-ycmd-setup)
|
||||
(flycheck-mode)))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-define-cquery-extensions ()
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'refs-address
|
||||
"textDocument/references"
|
||||
'(plist-put (lsp--text-document-position-params) :context '(:role 128)))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'refs-read
|
||||
"textDocument/references"
|
||||
'(plist-put (lsp--text-document-position-params) :context '(:role 8)))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'refs-write
|
||||
"textDocument/references"
|
||||
'(plist-put (lsp--text-document-position-params) :context '(:role 16)))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'callers "$cquery/callers")
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'callees "$cquery/callers" '(:callee t))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'base "$cquery/base"))
|
||||
(defun spacemacs//c-c++-setup-ycmd-semantic ()
|
||||
"Setup semantic for ycmd."
|
||||
(semantic-mode))
|
||||
|
||||
(defun spacemacs//c-c++-lsp-define-ccls-extensions ()
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'refs-address "textDocument/references" '(:role 128))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'refs-read "textDocument/references" '(:role 8))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'refs-write "textDocument/references" '(:role 16))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'callers "$ccls/call")
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'callees "$ccls/call" '(:callee t))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'base "$ccls/inheritance")
|
||||
;;ccls features without a cquery analogue...
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'derived "$ccls/inheritance" '(:derived t))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'member-types "$ccls/member" `(:kind 2))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'member-functions "$ccls/member" `(:kind 3))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'member-vars "$ccls/member" `(:kind 0)))
|
||||
|
||||
;; style
|
||||
|
||||
(defun spacemacs//c-c++-lsp-define-clangd-extensions ()
|
||||
;;
|
||||
;; None of these work...
|
||||
;; (spacemacs/lsp-define-extensions "c-c++" 'clangd-other-file "textDocument/switchSourceHeader" `(:TextDocumentIdentifier ,buffer-file-name))
|
||||
;; (spacemacs/lsp-define-extensions "c-c++" 'clangd-other-file "textDocument/switchSourceHeader" '(:TextDocumentIdentifier 'buffer-file-name))
|
||||
(spacemacs/lsp-define-extensions "c-c++" 'clangd-other-file "textDocument/switchSourceHeader" 'buffer-file-name)
|
||||
;; (spacemacs/lsp-define-extensions "c-c++" 'clangd-other-file "textDocument/switchSourceHeader")
|
||||
)
|
||||
(defun spacemacs//c-toggle-auto-newline ()
|
||||
"Toggle auto-newline."
|
||||
(c-toggle-auto-newline 1))
|
||||
|
||||
|
||||
;; clang
|
||||
|
||||
(defun spacemacs//c-c++-setup-clang-format ()
|
||||
"Setup clang format."
|
||||
(when c-c++-enable-clang-format-on-save
|
||||
(spacemacs/add-to-hooks 'spacemacs/clang-format-on-save c-c++-mode-hooks))
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/declare-prefix-for-mode mode "m=" "format")
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
"==" 'spacemacs/clang-format-region-or-buffer
|
||||
"=f" 'spacemacs/clang-format-function)))
|
||||
|
||||
(defun spacemacs/clang-format-function (&optional style)
|
||||
"Format the current function with clang-format according to STYLE."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(c-mark-function)
|
||||
(clang-format (region-beginning) (region-end) style)
|
||||
(deactivate-mark) ; If the function is already formatted, then remove the mark
|
||||
(message "Formatted function %s" (c-defun-name))))
|
||||
|
||||
(defun spacemacs/clang-format-region-or-buffer (&optional style)
|
||||
"Format the current region or buffer with clang-format according to STYLE."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(if (region-active-p)
|
||||
(progn
|
||||
(clang-format-region (region-beginning) (region-end) style)
|
||||
(message "Formatted region"))
|
||||
(progn
|
||||
(clang-format-buffer style)
|
||||
(message "Formatted buffer %s" (buffer-name))))))
|
||||
|
||||
(defun spacemacs//clang-format-on-save ()
|
||||
"Format the current buffer with clang-format on save when
|
||||
`c-c++-enable-clang-format-on-save' is non-nil."
|
||||
(when c-c++-enable-clang-format-on-save
|
||||
(spacemacs/clang-format-region-or-buffer)))
|
||||
|
||||
(defun spacemacs/clang-format-on-save ()
|
||||
"Add before-save hook for clang-format."
|
||||
(add-hook 'before-save-hook 'spacemacs//clang-format-on-save nil t))
|
||||
|
||||
|
||||
;; ccls
|
||||
|
||||
(defun spacemacs/c-c++-lsp-ccls-call-hierarchy-inv ()
|
||||
(interactive)
|
||||
(ccls-call-hierarchy t))
|
||||
|
||||
(defun spacemacs/c-c++-lsp-ccls-inheritance-hierarchy-inv ()
|
||||
(interactive)
|
||||
(ccls-inheritance-hierarchy t))
|
||||
|
||||
|
||||
;; cquery
|
||||
|
||||
(defun spacemacs/c-c++-lsp-cquery-call-hierarchy-inv ()
|
||||
(interactive)
|
||||
(cquery-call-hierarchy t))
|
||||
|
||||
(defun spacemacs/c-c++-lsp-cquery-inheritance-hierarchy-inv ()
|
||||
(interactive)
|
||||
(cquery-inheritance-hierarchy t))
|
||||
|
||||
|
||||
;; cpp-auto-include
|
||||
|
||||
(defalias 'spacemacs/c++-organize-includes 'cpp-auto-include)
|
||||
|
||||
(defun spacemacs//c++-organize-includes-on-save ()
|
||||
"Organize the includes on save when `c++-enable-organize-includes-on-save'
|
||||
is non-nil."
|
||||
(when c++-enable-organize-includes-on-save
|
||||
(spacemacs/c++-organize-includes)))
|
||||
|
||||
(defun spacemacs/c++-organize-includes-on-save ()
|
||||
"Add before-save hook for c++-organize-includes."
|
||||
(add-hook 'before-save-hook
|
||||
#'spacemacs//c++-organize-includes-on-save nil t))
|
||||
|
||||
(defun spacemacs//c-c++-setup-lsp-dap ()
|
||||
"Setup DAP integration."
|
||||
(require 'dap-lldb))
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
;;
|
||||
;;; License: GPLv3
|
||||
|
||||
(when (and (boundp 'c-c++-backend)
|
||||
(eq c-c++-backend 'lsp))
|
||||
(configuration-layer/declare-layer-dependencies '(lsp dap)))
|
||||
(when (fboundp 'spacemacs//c-c++-backend)
|
||||
(pcase (spacemacs//c-c++-backend)
|
||||
(`lsp-clangd (configuration-layer/declare-layer-dependencies '(lsp dap)))
|
||||
(`lsp-ccls (configuration-layer/declare-layer-dependencies '(lsp dap)))
|
||||
(`lsp-cquery (configuration-layer/declare-layer-dependencies '(lsp dap)))
|
||||
(`rtags (configuration-layer/declare-layer-dependencies '(ggtags)))
|
||||
(`ycmd (configuration-layer/declare-layer-dependencies '(ycmd)))))
|
||||
|
|
|
@ -13,46 +13,49 @@
|
|||
'(
|
||||
cc-mode
|
||||
clang-format
|
||||
company
|
||||
(company-c-headers :requires company)
|
||||
(company-rtags :requires company rtags)
|
||||
company-ycmd
|
||||
counsel-gtags
|
||||
(cpp-auto-include
|
||||
:location (recipe :fetcher github
|
||||
:repo "syohex/emacs-cpp-auto-include"))
|
||||
dap-mode
|
||||
disaster
|
||||
eldoc
|
||||
flycheck
|
||||
(flycheck-rtags :requires flycheck rtags)
|
||||
gdb-mi
|
||||
ggtags
|
||||
google-c-style
|
||||
helm-cscope
|
||||
helm-gtags
|
||||
(helm-rtags :requires helm rtags)
|
||||
(ivy-rtags :requires ivy rtags)
|
||||
lsp-mode ;;Owned/initialised by lsp-layer
|
||||
org
|
||||
projectile
|
||||
realgud
|
||||
rtags
|
||||
semantic
|
||||
srefactor
|
||||
stickyfunc-enhance
|
||||
xcscope
|
||||
ycmd
|
||||
;;lsp-backend
|
||||
(cquery :requires lsp-mode)
|
||||
;; lsp
|
||||
(ccls :requires lsp-mode)
|
||||
projectile
|
||||
))
|
||||
|
||||
(cquery :requires lsp-mode)
|
||||
dap-mode
|
||||
;; rtags
|
||||
(company-rtags :requires company rtags)
|
||||
counsel-gtags
|
||||
(flycheck-rtags :requires flycheck rtags)
|
||||
ggtags
|
||||
helm-gtags
|
||||
(helm-rtags :requires helm rtags)
|
||||
(ivy-rtags :requires ivy rtags)
|
||||
rtags
|
||||
;; ycmd
|
||||
(company-ycmd :requires company)
|
||||
(flycheck-ycmd :requires flycheck)
|
||||
ycmd))
|
||||
|
||||
(defun c-c++/init-cc-mode ()
|
||||
(use-package cc-mode
|
||||
:defer t
|
||||
:init
|
||||
(progn
|
||||
(add-hook 'c-mode-local-vars-hook #'spacemacs//c-c++-setup-backend)
|
||||
(add-hook 'c++-mode-local-vars-hook #'spacemacs//c-c++-setup-backend)
|
||||
(put 'c-c++-backend 'safe-local-variable 'symbolp)
|
||||
(when c-c++-default-mode-for-headers
|
||||
(add-to-list 'auto-mode-alist
|
||||
`("\\.h\\'" . ,c-c++-default-mode-for-headers)))
|
||||
|
@ -69,28 +72,17 @@
|
|||
"ga" 'projectile-find-other-file
|
||||
"gA" 'projectile-find-other-file-other-window)))))
|
||||
|
||||
(defun c-c++/init-ccls ()
|
||||
(use-package ccls))
|
||||
|
||||
(defun c-c++/init-clang-format ()
|
||||
(use-package clang-format
|
||||
:if (or c-c++-enable-clang-support (eq c-c++-backend 'lsp))
|
||||
:init
|
||||
(progn
|
||||
(when c-c++-enable-clang-format-on-save
|
||||
(spacemacs/add-to-hooks 'spacemacs/clang-format-on-save c-c++-mode-hooks))
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/declare-prefix-for-mode mode "m=" "format")
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
"==" 'spacemacs/clang-format-region-or-buffer
|
||||
"=f" 'spacemacs/clang-format-function)))))
|
||||
:init (spacemacs/add-to-hooks #'spacemacs//c-c++-setup-format
|
||||
c-c++-mode-hooks)))
|
||||
|
||||
(defun c-c++/post-init-company ()
|
||||
(when c-c++-enable-clang-support
|
||||
(if (eq c-c++-backend 'lsp)
|
||||
(display-warning :error "`c-c++-enable-clang-support' ignored when using lsp backend")
|
||||
(progn
|
||||
(spacemacs|add-company-backends :backends company-clang :modes c-mode-common)
|
||||
(setq company-clang-prefix-guesser 'spacemacs/company-more-than-prefix-guesser)
|
||||
(spacemacs/add-to-hooks 'spacemacs/c-c++-load-clang-args c-c++-mode-hooks)
|
||||
()))))
|
||||
(add-hook 'c-mode-local-vars-hook #'spacemacs//c-c++-setup-company)
|
||||
(add-hook 'c++-mode-local-vars-hook #'spacemacs//c-c++-setup-company))
|
||||
|
||||
(defun c-c++/init-company-c-headers ()
|
||||
(use-package company-c-headers
|
||||
|
@ -101,17 +93,12 @@
|
|||
|
||||
(defun c-c++/init-company-rtags ()
|
||||
(use-package company-rtags
|
||||
:if (and (eq c-c++-backend 'rtags) c-c++-enable-rtags-completion)
|
||||
:defer t
|
||||
:init
|
||||
(progn
|
||||
(setq rtags-completions-enabled t)
|
||||
(spacemacs|add-company-backends
|
||||
:backends company-rtags
|
||||
:modes c-mode-common))))
|
||||
:defer t))
|
||||
|
||||
(defun c-c++/post-init-company-ycmd ()
|
||||
(spacemacs|add-company-backends :backends company-ycmd :modes c-mode-common))
|
||||
(defun c-c++/init-company-ycmd ()
|
||||
(use-package company-ycmd
|
||||
:defer t
|
||||
:commands company-ycmd))
|
||||
|
||||
(defun c-c++/post-init-counsel-gtags ()
|
||||
(dolist (mode c-c++-modes)
|
||||
|
@ -130,6 +117,15 @@
|
|||
(spacemacs/set-leader-keys-for-major-mode 'c++-mode
|
||||
"ri" #'spacemacs/c++-organize-includes))))
|
||||
|
||||
(defun c-c++/init-cquery ()
|
||||
(use-package cquery))
|
||||
|
||||
(defun c-c++/pre-init-dap-mode ()
|
||||
(add-to-list 'spacemacs--dap-supported-modes 'c-mode)
|
||||
(add-to-list 'spacemacs--dap-supported-modes 'c++-mode)
|
||||
(add-hook 'c-mode-local-vars-hook #'spacemacs//c-c++-setup-dap)
|
||||
(add-hook 'c++-mode-local-vars-hook #'spacemacs//c-c++-setup-dap))
|
||||
|
||||
(defun c-c++/init-disaster ()
|
||||
(use-package disaster
|
||||
:defer t
|
||||
|
@ -140,16 +136,21 @@
|
|||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
"D" 'disaster)))))
|
||||
|
||||
(defun c-c++/post-init-flycheck ()
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/enable-flycheck mode))
|
||||
(when c-c++-enable-clang-support
|
||||
(spacemacs/add-to-hooks 'spacemacs/c-c++-load-clang-args c-c++-mode-hooks)))
|
||||
(defun c-c++/post-init-eldoc ()
|
||||
(add-hook 'c-mode-local-vars-hook #'spacemacs//c-c++-setup-eldoc)
|
||||
(add-hook 'c++-mode-local-vars-hook #'spacemacs//c-c++-setup-eldoc))
|
||||
|
||||
(defun c-c++/post-init-flycheck ()
|
||||
(add-hook 'c-mode-local-vars-hook #'spacemacs//c-c++-setup-flycheck)
|
||||
(add-hook 'c++-mode-local-vars-hook #'spacemacs//c-c++-setup-flycheck))
|
||||
|
||||
;; TODO lazy load this package
|
||||
(defun c-c++/init-flycheck-rtags ()
|
||||
(use-package flycheck-rtags
|
||||
:if (eq c-c++-backend 'rtags)))
|
||||
:defer t))
|
||||
|
||||
(defun c-c++/init-flycheck-ycmd ()
|
||||
(use-package flycheck-ycmd
|
||||
:defer t))
|
||||
|
||||
(defun c-c++/post-init-ggtags ()
|
||||
(add-hook 'c-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)
|
||||
|
@ -167,10 +168,13 @@
|
|||
|
||||
(defun c-c++/init-google-c-style ()
|
||||
(use-package google-c-style
|
||||
:if (or 'c-c++-enable-google-style 'c-c++-enable-google-newline)
|
||||
:config (progn
|
||||
(when c-c++-enable-google-style (add-hook 'c-mode-common-hook 'google-set-c-style))
|
||||
(when c-c++-enable-google-newline (add-hook 'c-mode-common-hook 'google-make-newline-indent)))))
|
||||
:defer t
|
||||
:init
|
||||
(progn
|
||||
(when c-c++-enable-google-style
|
||||
(add-hook 'c-mode-common-hook 'google-set-c-style))
|
||||
(when c-c++-enable-google-newline
|
||||
(add-hook 'c-mode-common-hook 'google-make-newline-indent)))))
|
||||
|
||||
(defun c-c++/pre-init-helm-cscope ()
|
||||
(spacemacs|use-package-add-hook xcscope
|
||||
|
@ -182,75 +186,45 @@
|
|||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/helm-gtags-define-keys-for-mode mode)))
|
||||
|
||||
;; TODO lazy load this package
|
||||
(defun c-c++/init-helm-rtags ()
|
||||
(use-package helm-rtags
|
||||
:if (eq c-c++-backend 'rtags)
|
||||
:defer t
|
||||
:init (setq rtags-display-result-backend 'helm)))
|
||||
|
||||
;; TODO lazy load this package
|
||||
(defun c-c++/init-ivy-rtags ()
|
||||
(use-package ivy-rtags
|
||||
:if (eq c-c++-backend 'rtags)
|
||||
:defer t
|
||||
:init (setq rtags-display-result-backend 'ivy)))
|
||||
|
||||
;; TODO lazy load this package
|
||||
(defun c-c++/init-rtags ()
|
||||
(use-package rtags
|
||||
:if (eq c-c++-backend 'rtags)
|
||||
:init
|
||||
(defun c-c++/pre-init-org ()
|
||||
(spacemacs|use-package-add-hook org
|
||||
:post-config (add-to-list 'org-babel-load-languages '(C . t))))
|
||||
|
||||
(defun c-c++/pre-init-projectile ()
|
||||
(spacemacs|use-package-add-hook projectile
|
||||
:post-config
|
||||
(progn
|
||||
(setq rtags-autostart-diagnostics t)
|
||||
(add-hook 'rtags-jump-hook 'evil-set-jump)
|
||||
(rtags-diagnostics)
|
||||
;; key bindings
|
||||
(evil-define-key 'normal rtags-mode-map
|
||||
(kbd "RET") 'rtags-select-other-window
|
||||
(kbd "M-RET") 'rtags-select
|
||||
(kbd "q") 'rtags-bury-or-delete)
|
||||
;; TODO check for consistency with gtags key bindings
|
||||
;; see https://github.com/syl20bnr/spacemacs/blob/develop/layers/+tags/gtags/funcs.el#L70
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
"g." 'spacemacs/c-c++-tags-find-symbol-at-point
|
||||
"g," 'spacemacs/c-c++-tags-find-references-at-point
|
||||
"g;" 'spacemacs/c-c++-tags-find-file
|
||||
"g/" 'rtags-find-all-references-at-point
|
||||
"g[" 'rtags-location-stack-back
|
||||
"g]" 'rtags-location-stack-forward
|
||||
"g>" 'spacemacs/c-c++-tags-find-symbol
|
||||
"g<" 'spacemacs/c-c++-tags-find-references
|
||||
"gB" 'rtags-show-rtags-buffer
|
||||
"gd" 'rtags-print-dependencies
|
||||
"gD" 'rtags-diagnostics
|
||||
"ge" 'rtags-reparse-file
|
||||
"gE" 'rtags-preprocess-file
|
||||
"gF" 'rtags-fixit
|
||||
"gG" 'rtags-guess-function-at-point
|
||||
"gh" 'rtags-print-class-hierarchy
|
||||
"gI" 'spacemacs/c-c++-tags-imenu
|
||||
"gL" 'rtags-copy-and-print-current-location
|
||||
"gM" 'rtags-symbol-info
|
||||
"gO" 'rtags-goto-offset
|
||||
"gp" 'rtags-set-current-project
|
||||
"gR" 'rtags-rename-symbol
|
||||
"gs" 'rtags-print-source-arguments
|
||||
"gS" 'rtags-display-summary
|
||||
"gT" 'rtags-taglist
|
||||
"gv" 'rtags-find-virtuals-at-point
|
||||
"gV" 'rtags-print-enum-value-at-point
|
||||
"gX" 'rtags-fix-fixit-at-point
|
||||
"gY" 'rtags-cycle-through-diagnostics)))))
|
||||
;; Ignore lsp cache dir, in case user has opted for cache within project source tree
|
||||
(add-to-list 'projectile-globally-ignored-directories c-c++-lsp-cache-dir)
|
||||
(when c-c++-adopt-subprojects
|
||||
(setq projectile-project-root-files-top-down-recurring
|
||||
(append '("compile_commands.json"
|
||||
".cquery"
|
||||
".ccls")
|
||||
projectile-project-root-files-top-down-recurring))))))
|
||||
|
||||
(defun c-c++/init-rtags ()
|
||||
;; config in `funcs.el'
|
||||
(use-package rtags
|
||||
:defer t))
|
||||
|
||||
(defun c-c++/post-init-realgud()
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/add-realgud-debugger mode "gdb")))
|
||||
|
||||
(defun c-c++/post-init-semantic ()
|
||||
(spacemacs/add-to-hooks 'semantic-mode c-c++-mode-hooks)
|
||||
(when (or (configuration-layer/layer-used-p 'gtags)
|
||||
(configuration-layer/layer-used-p 'lsp))
|
||||
(spacemacs/add-to-hooks 'spacemacs//disable-semantic-idle-summary-mode c-c++-mode-hooks t)))
|
||||
(add-hook 'c-mode-local-vars-hook #'spacemacs//c-c++-setup-semantic)
|
||||
(add-hook 'c++-mode-local-vars-hook #'spacemacs//c-c++-setup-semantic))
|
||||
|
||||
(defun c-c++/post-init-srefactor ()
|
||||
(dolist (mode c-c++-modes)
|
||||
|
@ -260,60 +234,19 @@
|
|||
(defun c-c++/post-init-stickyfunc-enhance ()
|
||||
(spacemacs/add-to-hooks 'spacemacs/load-stickyfunc-enhance c-c++-mode-hooks))
|
||||
|
||||
(defun c-c++/post-init-ycmd ()
|
||||
(spacemacs/add-to-hooks 'ycmd-mode c-c++-mode-hooks)
|
||||
(add-to-list 'spacemacs-jump-handlers-c++-mode '(ycmd-goto :async t))
|
||||
(add-to-list 'spacemacs-jump-handlers-c-mode '(ycmd-goto :async t))
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode
|
||||
"gG" 'ycmd-goto-imprecise)))
|
||||
|
||||
(defun c-c++/pre-init-org ()
|
||||
(spacemacs|use-package-add-hook org
|
||||
:post-config (add-to-list 'org-babel-load-languages '(C . t))))
|
||||
|
||||
(defun c-c++/pre-init-xcscope ()
|
||||
(spacemacs|use-package-add-hook xcscope
|
||||
:post-init
|
||||
(dolist (mode c-c++-modes)
|
||||
(spacemacs/set-leader-keys-for-major-mode mode "gi" 'cscope-index-files))))
|
||||
|
||||
;; BEGIN LSP BACKEND PACKAGES
|
||||
(defun c-c++/post-init-lsp-mode ()
|
||||
(when (eq c-c++-backend 'lsp)
|
||||
(spacemacs//c-c++-lsp-config)
|
||||
(unless (eq c-c++-lsp-server 'clangd)
|
||||
(require c-c++-lsp-server) ; i.e. the 'ccls or 'cquery package
|
||||
(remhash 'clangd lsp-clients))
|
||||
(spacemacs/add-to-hooks 'lsp c-c++-mode-hooks)))
|
||||
|
||||
;; See also https://github.com/cquery-project/cquery/wiki/Emacs
|
||||
(defun c-c++/init-cquery ()
|
||||
(use-package cquery
|
||||
:if (and (eq c-c++-backend 'lsp) (eq c-c++-lsp-server 'cquery))))
|
||||
|
||||
;; See also https://github.com/MaskRay/ccls/wiki/Emacs
|
||||
(defun c-c++/init-ccls ()
|
||||
(use-package ccls
|
||||
:if (and (eq c-c++-backend 'lsp) (eq c-c++-lsp-server 'ccls))))
|
||||
|
||||
(defun c-c++/pre-init-projectile ()
|
||||
(spacemacs|use-package-add-hook projectile
|
||||
:post-config
|
||||
(defun c-c++/init-ycmd ()
|
||||
(use-package ycmd
|
||||
:defer t
|
||||
:init
|
||||
(progn
|
||||
(when c-c++-lsp-cache-dir
|
||||
;; Ignore lsp cache dir, in case user has opted for cache within project source tree
|
||||
(add-to-list 'projectile-globally-ignored-directories c-c++-lsp-cache-dir))
|
||||
(when c-c++-adopt-subprojects
|
||||
(setq projectile-project-root-files-top-down-recurring
|
||||
(append '("compile_commands.json"
|
||||
".cquery"
|
||||
".ccls")
|
||||
projectile-project-root-files-top-down-recurring))))))
|
||||
|
||||
;; END LSP BACKEND PACKAGES
|
||||
|
||||
(defun c-c++/pre-init-dap-mode ()
|
||||
(dolist (mode c-c++-modes)
|
||||
(add-to-list 'spacemacs--dap-supported-modes mode)
|
||||
(when (eq c-c++-backend 'lsp) (spacemacs/add-to-hooks 'spacemacs//c-c++-setup-lsp-dap c-c++-mode-hooks))))
|
||||
(unless (boundp 'ycmd-global-config)
|
||||
(setq-default ycmd-global-config
|
||||
(concat (configuration-layer/get-layer-path 'ycmd)
|
||||
"global_conf.py")))
|
||||
(setq-default ycmd-parse-conditions '(save mode-enabled)))))
|
||||
|
|
|
@ -15,6 +15,18 @@
|
|||
(add-to-list (intern (format "spacemacs-jump-handlers-%S" m))
|
||||
'(lsp-ui-peek-find-definitions :async t))))
|
||||
|
||||
|
||||
;; Key bindings
|
||||
|
||||
;; Used for lsp-ui-peek-mode, but may be able to use some spacemacs fn. instead?
|
||||
(defun spacemacs/lsp-define-key (keymap key def &rest bindings)
|
||||
"Define multiple key bindings with KEYMAP KEY DEF BINDINGS."
|
||||
(interactive)
|
||||
(while key
|
||||
(define-key keymap (kbd key) def)
|
||||
(setq key (pop bindings)
|
||||
def (pop bindings))))
|
||||
|
||||
(defun spacemacs/lsp-bind-keys ()
|
||||
"Define key bindings for the lsp minor mode."
|
||||
(ecase lsp-navigation
|
||||
|
@ -63,8 +75,7 @@
|
|||
;; text/code
|
||||
"xh" #'lsp-document-highlight
|
||||
"xl" #'lsp-lens-show
|
||||
"xL" #'lsp-lens-hide
|
||||
))
|
||||
"xL" #'lsp-lens-hide))
|
||||
|
||||
(defun spacemacs//lsp-bind-simple-navigation-functions (prefix-char)
|
||||
(spacemacs/set-leader-keys-for-minor-mode 'lsp-mode
|
||||
|
@ -78,8 +89,7 @@
|
|||
(concat prefix-char "s") #'helm-lsp-workspace-symbol
|
||||
(concat prefix-char "S") #'helm-lsp-global-workspace-symbol)
|
||||
(spacemacs/set-leader-keys-for-minor-mode 'lsp-mode
|
||||
(concat prefix-char "s") #'lsp-ui-find-workspace-symbol))
|
||||
)
|
||||
(concat prefix-char "s") #'lsp-ui-find-workspace-symbol)))
|
||||
|
||||
(defun spacemacs//lsp-bind-peek-navigation-functions (prefix-char)
|
||||
(spacemacs/set-leader-keys-for-minor-mode 'lsp-mode
|
||||
|
@ -95,7 +105,7 @@
|
|||
(defun spacemacs//lsp-declare-prefixes-for-mode (mode)
|
||||
"Define key binding prefixes for the specific MODE."
|
||||
(unless (member mode lsp-layer--active-mode-list)
|
||||
(push mode lsp-layer--active-mode-list)
|
||||
(add-to-list 'lsp-layer--active-mode-list mode)
|
||||
(spacemacs/declare-prefix-for-mode mode "m=" "format")
|
||||
(spacemacs/declare-prefix-for-mode mode "ma" "code actions")
|
||||
(spacemacs/declare-prefix-for-mode mode "mb" "backend")
|
||||
|
@ -110,6 +120,130 @@
|
|||
(spacemacs/declare-prefix-for-mode mode (concat prefix "h") "hierarchy")
|
||||
(spacemacs/declare-prefix-for-mode mode (concat prefix "m") "members"))))
|
||||
|
||||
(defun spacemacs//lsp-bind-extensions-for-mode (mode
|
||||
layer-name
|
||||
backend-name
|
||||
key
|
||||
kind)
|
||||
"Bind extensions under the appropriate prefix(es) for the major-mode MODE.
|
||||
MODE should be a quoted symbol corresponding to a valid major mode.
|
||||
|
||||
LAYER-NAME is the name string of the layer
|
||||
BACKEND-NAME is the name string of the back-end set for the layer
|
||||
KEY is a string corresponding to a key sequence
|
||||
KIND is a quoted symbol corresponding to an extension defined using
|
||||
`lsp-define-extensions'."
|
||||
(ecase lsp-navigation
|
||||
('simple (spacemacs/set-leader-keys-for-major-mode mode
|
||||
(concat "g" key)
|
||||
(spacemacs//lsp-extension-name
|
||||
layer-name backend-name "find" kind)))
|
||||
('peek (spacemacs/set-leader-keys-for-major-mode mode
|
||||
(concat "g" key)
|
||||
(spacemacs//lsp-extension-name
|
||||
layer-name backend-name "peek" kind)))
|
||||
('both (spacemacs/set-leader-keys-for-major-mode mode
|
||||
(concat "g" key)
|
||||
(spacemacs//lsp-extension-name
|
||||
layer-name backend-name "find" kind)
|
||||
(concat "G" key)
|
||||
(spacemacs//lsp-extension-name
|
||||
layer-name backend-name "peek" kind)))))
|
||||
|
||||
(defun spacemacs/lsp-bind-extensions-for-mode (mode
|
||||
layer-name
|
||||
backend-name
|
||||
key
|
||||
kind
|
||||
&rest bindings)
|
||||
"Bind extensions under the appropriate prefix(es) for the major-mode MODE.
|
||||
|
||||
MODE is a quoted symbol corresponding to a valid major mode.
|
||||
LAYER-NAME is the name string of the layer
|
||||
BACKEND-NAME is the name string of the back-end set for the layer
|
||||
KEY is a string corresponding to a key sequence
|
||||
KIND is a quoted symbol corresponding to an extension defined using
|
||||
`lsp-define-extensions'.
|
||||
BINDINGS is other KEY and KIND to create other key bindings."
|
||||
(while key
|
||||
(spacemacs//lsp-bind-extensions-for-mode mode layer-name backend-name key kind)
|
||||
(setq key (pop bindings)
|
||||
kind (pop bindings))))
|
||||
|
||||
|
||||
;; Extensions
|
||||
|
||||
(defun spacemacs/lsp-define-extensions (layer-name
|
||||
backend-name
|
||||
kind
|
||||
request
|
||||
&optional extra)
|
||||
"Wrap backend-specific LSP extensions.
|
||||
|
||||
This function uses using `lsp-find-custom' and `lsp-ui-peek-find-custom'.
|
||||
The function names are defined in `spacemacs//lsp-extension-name.'"
|
||||
(dolist (nav-mode '("find" "peek"))
|
||||
(if extra
|
||||
(spacemacs//lsp-define-custom-extension
|
||||
layer-name backend-name nav-mode kind request extra)
|
||||
(spacemacs//lsp-define-custom-extension
|
||||
layer-name backend-name nav-mode kind request))))
|
||||
|
||||
(defun spacemacs//lsp-extension-name (layer-name backend-name nav-mode kind)
|
||||
"Return the extension name.
|
||||
|
||||
Pattern is `spacemacs/<layer-name>-<backend-end>-<nav-mode>-<kind>'.
|
||||
|
||||
Examples of return name:
|
||||
- spacemacs/c-c++-lsp-clangd-find-clangd-other-file
|
||||
- spacemacs/c-c++-lsp-clangd-peek-clangd-other-file
|
||||
|
||||
LAYER-NAME is the name string of the layer
|
||||
BACKEND-NAME is the name string of the back-end set for the layer
|
||||
NAV-MODE is a string with value `peek' or `find'
|
||||
KIND is a quoted symbol corresponding to an extension defined using
|
||||
`lsp-define-extensions'."
|
||||
(intern
|
||||
(concat "spacemacs/"
|
||||
layer-name "-" backend-name "-" nav-mode "-" (symbol-name kind))))
|
||||
|
||||
(defun spacemacs//lsp-define-custom-extension (layer-name
|
||||
backend-name
|
||||
nav-mode
|
||||
kind
|
||||
request
|
||||
&optional extra)
|
||||
"Helper function to define custom LSP extensions.
|
||||
|
||||
LAYER-NAME is the name string of the layer
|
||||
BACKEND-NAME is the name string of the back-end set for the layer
|
||||
NAV-MODE is a string with value `peek' or `find'
|
||||
KIND is a quoted symbol corresponding to an extension defined using
|
||||
`lsp-define-extensions'.
|
||||
REQUEST is a string defining the request
|
||||
EXTRA is an additional parameter pass to LSP function"
|
||||
(let ((lsp-extension-fn (if (equal nav-mode "find")
|
||||
'lsp-find-locations
|
||||
'lsp-ui-peek-find-custom))
|
||||
(extension-name (spacemacs//lsp-extension-name
|
||||
layer-name backend-name nav-mode kind))
|
||||
(extension-descriptor (format (concat nav-mode " %s")
|
||||
(symbol-name kind))))
|
||||
(if extra
|
||||
(defalias extension-name
|
||||
`(lambda ()
|
||||
,extension-descriptor
|
||||
(interactive)
|
||||
(funcall ',lsp-extension-fn ,request ',extra)))
|
||||
(defalias extension-name
|
||||
`(lambda ()
|
||||
,extension-descriptor
|
||||
(interactive)
|
||||
(funcall ',lsp-extension-fn ,request))))))
|
||||
|
||||
|
||||
;; Utils
|
||||
|
||||
(defun spacemacs/lsp-ui-doc-func ()
|
||||
"Toggle the function signature in the lsp-ui-doc overlay"
|
||||
(interactive)
|
||||
|
@ -124,72 +258,16 @@
|
|||
(defun spacemacs/lsp-ui-sideline-ignore-duplicate ()
|
||||
"Toggle ignore duplicates for lsp-ui-sideline overlay"
|
||||
(interactive)
|
||||
(setq lsp-ui-sideline-ignore-duplicate (not lsp-ui-sideline-ignore-duplicate)))
|
||||
|
||||
;; Used for lsp-ui-peek-mode, but may be able to use some spacemacs fn. instead?
|
||||
(defun spacemacs/lsp-define-key (keymap key def &rest bindings)
|
||||
"Define multiple key bindings with KEYMAP KEY DEF BINDINGS."
|
||||
(interactive)
|
||||
(while key
|
||||
(define-key keymap (kbd key) def)
|
||||
(setq key (pop bindings)
|
||||
def (pop bindings))))
|
||||
|
||||
;; These functions facilitate extension of the navigation-mode keybindings in derived layers
|
||||
;; See c/c++ layer for a usage example
|
||||
(defun spacemacs//lsp-get-extension-name (layer-name nav-mode kind)
|
||||
(intern (concat layer-name "/" nav-mode "-" (symbol-name kind))))
|
||||
|
||||
(defun spacemacs//lsp-define-custom-extension (layer-name nav-mode kind request &optional extra)
|
||||
(let ((lsp-extension-fn (if (equal nav-mode "find")
|
||||
'lsp-find-locations
|
||||
'lsp-ui-peek-find-custom))
|
||||
(extension-name (spacemacs//lsp-get-extension-name layer-name nav-mode kind))
|
||||
(extension-descriptor (format (concat nav-mode " %s") (symbol-name kind))))
|
||||
(if extra
|
||||
(defalias extension-name `(lambda () ,extension-descriptor (interactive) (funcall ',lsp-extension-fn ,request ',extra)))
|
||||
(defalias extension-name `(lambda () ,extension-descriptor (interactive) (funcall ',lsp-extension-fn ,request))))))
|
||||
|
||||
(defun spacemacs/lsp-define-extensions (layer-name kind request &optional extra)
|
||||
"Wrap backend-specific LSP extensions using lsp-find-custom and lsp-ui-peek-find-custom.
|
||||
The function names will be <layer-name>/find-<kind> and <layer-name>/peek-<kind>, respectively."
|
||||
(dolist (nav-mode '("find" "peek"))
|
||||
(if extra
|
||||
(spacemacs//lsp-define-custom-extension layer-name nav-mode kind request extra)
|
||||
(spacemacs//lsp-define-custom-extension layer-name nav-mode kind request))))
|
||||
|
||||
(defun spacemacs//lsp-bind-extensions (mode layer-name key kind)
|
||||
(ecase lsp-navigation
|
||||
('simple (spacemacs/set-leader-keys-for-major-mode mode
|
||||
(concat "g" key) (spacemacs//lsp-get-extension-name layer-name "find" kind)))
|
||||
('peek (spacemacs/set-leader-keys-for-major-mode mode
|
||||
(concat "g" key) (spacemacs//lsp-get-extension-name layer-name "peek" kind)))
|
||||
('both (spacemacs/set-leader-keys-for-major-mode mode
|
||||
(concat "g" key) (spacemacs//lsp-get-extension-name layer-name "find" kind)
|
||||
(concat "G" key) (spacemacs//lsp-get-extension-name layer-name "peek" kind)))))
|
||||
|
||||
(defun spacemacs/lsp-bind-extensions-for-mode (mode layer-name key kind &rest bindings)
|
||||
"Bind find/peek extensions under the appropriate prefix(es) for the major-mode
|
||||
MODE. MODE should be a quoted symbol corresponding to a valid major mode.
|
||||
LAYER-NAME and KEY should be quoted strings. KIND should be quoted symbol corresponding to
|
||||
a find extension defined using `lsp-define-extensions'"
|
||||
(while key
|
||||
(spacemacs//lsp-bind-extensions mode layer-name key kind)
|
||||
(setq key (pop bindings) kind (pop bindings))))
|
||||
|
||||
(defun spacemacs/lsp-avy-goto-word ()
|
||||
(interactive)
|
||||
(spacemacs//lsp-avy-document-symbol t))
|
||||
|
||||
(defun spacemacs/lsp-avy-goto-symbol ()
|
||||
(interactive)
|
||||
(spacemacs//lsp-avy-document-symbol nil))
|
||||
(setq lsp-ui-sideline-ignore-duplicate
|
||||
(not lsp-ui-sideline-ignore-duplicate)))
|
||||
|
||||
(defun spacemacs//lsp-action-placeholder ()
|
||||
(interactive)
|
||||
(message "Watch this space... (to be implemented in 'lsp-mode)"))
|
||||
(message "Not supported yet... (to be implemented in 'lsp-mode')"))
|
||||
|
||||
|
||||
;; ivy integration
|
||||
|
||||
;; From https://github.com/MaskRay/Config/blob/master/home/.config/doom/autoload/misc.el#L118
|
||||
(defun spacemacs//lsp-avy-document-symbol (all)
|
||||
(interactive)
|
||||
(let ((line 0) (col 0) (w (selected-window))
|
||||
|
@ -201,12 +279,15 @@ a find extension defined using `lsp-define-extensions'"
|
|||
(save-excursion
|
||||
(goto-char 1)
|
||||
(cl-loop for loc in
|
||||
(lsp--send-request (lsp--make-request
|
||||
"textDocument/documentSymbol"
|
||||
`(:textDocument ,(lsp--text-document-identifier)
|
||||
:all ,(if all t :json-false)
|
||||
:startLine ,start-line :endLine ,end-line)))
|
||||
for range = (if ccls loc (->> loc (gethash "location") (gethash "range")))
|
||||
(lsp--send-request
|
||||
(lsp--make-request
|
||||
"textDocument/documentSymbol"
|
||||
`(:textDocument ,(lsp--text-document-identifier)
|
||||
:all ,(if all t :json-false)
|
||||
:startLine ,start-line :endLine ,end-line)))
|
||||
for range = (if ccls
|
||||
loc
|
||||
(->> loc (gethash "location") (gethash "range")))
|
||||
for range_start = (gethash "start" range)
|
||||
for range_end = (gethash "end" range)
|
||||
for l0 = (gethash "line" range_start)
|
||||
|
@ -224,7 +305,14 @@ a find extension defined using `lsp-define-extensions'"
|
|||
(setq point1 (point))
|
||||
(setq line l1 col c1)
|
||||
(push `((,point0 . ,point1) . ,w) candidates)))
|
||||
;; (require 'avy)
|
||||
(avy-with avy-document-symbol
|
||||
(avy--process candidates
|
||||
(avy--style-fn avy-style)))))
|
||||
|
||||
(defun spacemacs/lsp-avy-goto-word ()
|
||||
(interactive)
|
||||
(spacemacs//lsp-avy-document-symbol t))
|
||||
|
||||
(defun spacemacs/lsp-avy-goto-symbol ()
|
||||
(interactive)
|
||||
(spacemacs//lsp-avy-document-symbol nil))
|
||||
|
|
Loading…
Reference in New Issue