Switch from LSP to Eglot
Python + Ruby + Rust ...
This commit is contained in:
parent
6b63130e76
commit
58e18451d6
6 changed files with 92 additions and 314 deletions
|
|
@ -318,85 +318,6 @@ This allows me to delete a Python “block” using ~dal~.
|
||||||
("Misc"
|
("Misc"
|
||||||
(("t" python-tests/body "Tests..."))))))
|
(("t" python-tests/body "Tests..."))))))
|
||||||
#+end_src
|
#+end_src
|
||||||
* Elpy
|
|
||||||
The [[https://elpy.readthedocs.io/en/latest/introduction.html][Elpy Project]] expands on the =python-mode=.
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(use-package elpy
|
|
||||||
:init
|
|
||||||
(advice-add 'python-mode :before 'elpy-enable)
|
|
||||||
:config
|
|
||||||
;; (elpy-enable)
|
|
||||||
(setq elpy-test-runner 'elpy-test-pytest-runner)
|
|
||||||
(setq elpy-formatter 'black)
|
|
||||||
(setq elpy-shell-echo-input nil)
|
|
||||||
(setq elpy-modules (delq 'elpy-module-flymake elpy-modules)))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
Elpy uses its *own* virtual environment for its backend process (jedi, rope, etc.), keeping elpy's own dependencies out of your project venvs. While there is a [[help:elpy-rpc-reinstall-virtualenv][elpy-rpc-reinstall-virtualenv]] function, I find it doesn’t seem to install everything correctly, and I need to do this by hand:
|
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
source ~/.emacs.d/elpy/rpc-venv/bin/activate
|
|
||||||
pip install jedi black flake8 ipython
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
After we’ve loaded the Company section, we can add jedi to the list of completions:
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(use-package elpy
|
|
||||||
:after company-mode
|
|
||||||
:config (add-to-list 'company-backends 'company-jedi))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
Let’s expand our =major-mode-hydra= with some extras:
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(use-package major-mode-hydra
|
|
||||||
:after elpy
|
|
||||||
:config
|
|
||||||
|
|
||||||
(pretty-hydra-define python-evaluate (:color blue :quit-key "q"
|
|
||||||
:title ha-python-eval-title)
|
|
||||||
("Section"
|
|
||||||
(("F" elpy-shell-send-defun "Function")
|
|
||||||
("E" elpy-shell-send-statement "Statement")
|
|
||||||
(";" python-shell-send-string "Expression"))
|
|
||||||
"Entirety"
|
|
||||||
(("B" elpy-shell-send-buffer "Buffer")
|
|
||||||
("r" elpy-shell-send-region-or-buffer "region"))
|
|
||||||
"And Step..."
|
|
||||||
(("f" elpy-shell-send-defun-and-step "Function" :color pink)
|
|
||||||
("e" elpy-shell-send-statement-and-step "Statement" :color pink))))
|
|
||||||
|
|
||||||
(pretty-hydra-define+ python-refactor nil
|
|
||||||
("Elpy"
|
|
||||||
(("r" elpy-refactor-rename "Rename")
|
|
||||||
("i" elpy-refactor-inline "Inline var")
|
|
||||||
("v" elpy-refactor-extract-variable "To variable")
|
|
||||||
("f" elpy-refactor-extract-function "To function")
|
|
||||||
("a" elpy-refactor-mode "All..."))))
|
|
||||||
|
|
||||||
(major-mode-hydra-define+ python-mode (:quit-key "q" :color blue)
|
|
||||||
("Server"
|
|
||||||
(("s" elpy-shell-switch-to-shell "Go to Server")
|
|
||||||
("C" elpy-config "Config Elpy"))
|
|
||||||
"Edit"
|
|
||||||
(("f" elpy-black-fix-code "Fix/format code"))
|
|
||||||
"Docs"
|
|
||||||
(("d" elpy-eldoc-documentation "Describe Symbol")
|
|
||||||
("D" elpy-doc "Docs Symbol")))))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
* Anaconda
|
|
||||||
The [[https://github.com/pythonic-emacs/anaconda-mode][anaconda-mode project]] seems as good as Elpy, but also include Evil keybindings.
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp :tangle no
|
|
||||||
(use-mode anaconda-mode
|
|
||||||
:hook ((python-mode . anaconda-mode)
|
|
||||||
(python-mode ../ anaconda-eldoc-mode)))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
Since we are using
|
|
||||||
* LSP Integration of Python
|
* LSP Integration of Python
|
||||||
** Dependencies
|
** Dependencies
|
||||||
Each Python project's =requirements-dev.txt= file would reference the [[https://pypi.org/project/python-lsp-server/][python-lsp-server]] (not the /unmaintained/ project, =python-language-server=):
|
Each Python project's =requirements-dev.txt= file would reference the [[https://pypi.org/project/python-lsp-server/][python-lsp-server]] (not the /unmaintained/ project, =python-language-server=):
|
||||||
|
|
@ -422,100 +343,60 @@ Each Python project's =requirements-dev.txt= file would reference the [[https://
|
||||||
# ...
|
# ...
|
||||||
#+end_src
|
#+end_src
|
||||||
** Pyright
|
** Pyright
|
||||||
I’m using the Microsoft-supported [[https://github.com/Microsoft/pyright][pyright]] package instead. Adding this to my =requirements.txt= files:
|
I’m using the Microsoft-supported [[https://github.com/Microsoft/pyright][pyright]] package instead, adding it to the global Python scope.
|
||||||
|
|
||||||
#+begin_src conf :tangle no
|
#+begin_src conf :tangle no
|
||||||
pyright
|
pyright
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
The [[https://github.com/emacs-lsp/lsp-pyright][pyright package]] works with LSP.
|
While the [[https://github.com/emacs-lsp/lsp-pyright][pyright package]] works with LSP, this isn’t needed, as =eglot= works directly with it.
|
||||||
|
** eglot
|
||||||
|
The built-in Eglot package natively supports [[https://github.com/Microsoft/pyright][pyright]] via =eglot-server-programs= (no extra package needed):
|
||||||
|
|
||||||
#+begin_src emacs-lisp :tangle no
|
#+begin_src emacs-lisp
|
||||||
(use-package lsp-pyright
|
(use-package eglot
|
||||||
:hook (python-mode . (lambda () (require 'lsp-pyright)))
|
:straight nil
|
||||||
:init (when (executable-find "python3")
|
:after python
|
||||||
(setq lsp-pyright-python-executable-cmd "python3")))
|
:defer t
|
||||||
|
:hook (python-mode . eglot-ensure)
|
||||||
|
:config
|
||||||
|
(add-to-list 'eglot-server-programs
|
||||||
|
'((python-mode python-ts-mode) . ("pyright-langserver" "--stdio"))))
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Keybindings
|
|
||||||
Now that the [[file:ha-programming.org::*Language Server Protocol (LSP) Integration][LSP Integration]] is complete, we can stitch the two projects together, by calling =lsp=. I oscillate between automatically turning on LSP mode with every Python file, but I sometimes run into issues when starting, so I conditionally turn it on.
|
Keybindings for the eglot-based LSP sub-menu, wired into the existing =python-mode= hydra:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defvar ha-python-lsp-title (font-icons 'faicon "python" :title "Python LSP"))
|
(defvar ha-python-lsp-title (font-icons 'faicon "python" :title "Python LSP"))
|
||||||
|
|
||||||
(defun ha-setup-python-lsp ()
|
(use-package eglot
|
||||||
"Configure the keybindings for LSP in Python."
|
:straight nil
|
||||||
(interactive)
|
:after major-mode-hydra
|
||||||
|
:config
|
||||||
(pretty-hydra-define python-lsp (:color blue :quit-key "q"
|
(pretty-hydra-define python-lsp (:color blue :quit-key "q"
|
||||||
:title ha-python-lsp-title)
|
:title ha-python-lsp-title)
|
||||||
("Server"
|
("Server"
|
||||||
(("D" lsp-disconnect "Disconnect")
|
(("D" eglot-shutdown "Disconnect")
|
||||||
("R" lsp-workspace-restart "Restart")
|
("R" eglot-reconnect "Reconnect")
|
||||||
("S" lsp-workspace-shutdown "Shutdown")
|
("?" eglot-show-workspace-configuration "Describe"))
|
||||||
("?" lsp-describe-session "Describe"))
|
|
||||||
"Refactoring"
|
"Refactoring"
|
||||||
(("a" lsp-execute-code-action "Code Actions")
|
(("a" eglot-code-actions "Code Actions")
|
||||||
("o" lsp-organize-imports "Organize Imports")
|
("o" eglot-code-action-organize-imports "Organize Imports")
|
||||||
("l" lsp-avy-lens "Avy Lens"))
|
("r" eglot-rename "Rename"))
|
||||||
"Toggles"
|
"Navigation"
|
||||||
(("b" lsp-headerline-breadcrumb-mode "Breadcrumbs")
|
(("." xref-find-definitions "Definition")
|
||||||
("d" lsp-ui-doc-mode "Documentation Popups")
|
("/" xref-find-references "References")
|
||||||
("m" lsp-modeline-diagnostics-mode "Modeline Diagnostics")
|
("t" eglot-find-typeDefinition "Type Definition")
|
||||||
("s" lsp-ui-sideline-mode "Sideline Mode"))
|
("i" eglot-find-implementation "Implementation"))
|
||||||
""
|
|
||||||
(("t" lsp-toggle-on-type-formatting "Type Formatting")
|
|
||||||
("h" lsp-toggle-symbol-highlight "Symbol Highlighting")
|
|
||||||
("L" lsp-toggle-trace-io "Log I/O"))))
|
|
||||||
|
|
||||||
(pretty-hydra-define+ python-goto (:quit-key "q")
|
|
||||||
("LSP"
|
|
||||||
(("g" lsp-find-definition "Definition")
|
|
||||||
("d" lsp-find-declaration "Declaration")
|
|
||||||
("r" lsp-find-references "References")
|
|
||||||
("t" lsp-find-type-definition "Type Definition"))
|
|
||||||
"Peek"
|
|
||||||
(("D" lsp-ui-peek-find-definitions "Definitions")
|
|
||||||
("I" lsp-ui-peek-find-implementation "Implementations")
|
|
||||||
("R" lsp-ui-peek-find-references "References")
|
|
||||||
("S" lsp-ui-peek-find-workspace-symbol "Symbols"))
|
|
||||||
"LSP+"
|
|
||||||
(("u" lsp-ui-imenu "UI Menu")
|
|
||||||
("i" lsp-find-implementation "Implementations")
|
|
||||||
("h" lsp-treemacs-call-hierarchy "Hierarchy")
|
|
||||||
("E" lsp-treemacs-errors-list "Error List"))))
|
|
||||||
|
|
||||||
(major-mode-hydra-define+ python-mode nil
|
|
||||||
("Server"
|
|
||||||
(("l" python-lsp/body "LSP..."))
|
|
||||||
"Edit"
|
|
||||||
(("=" lsp-format-region "Format"))
|
|
||||||
"Navigate"
|
|
||||||
(("A" lsp-workspace-folders-add "Add Folder")
|
|
||||||
("R" lsp-workspace-folders-remove "Remove Folder"))
|
|
||||||
"Docs"
|
"Docs"
|
||||||
(("D" lsp-describe-thing-at-point "Describe LSP Symbol")
|
(("d" eldoc-doc-buffer "Eldoc Buffer")
|
||||||
("h" lsp-ui-doc-glance "Glance Help")
|
("h" eglot-inlay-hints-mode "Inlay Hints")
|
||||||
("H" lsp-document-highlight "Highlight"))))
|
("=" eglot-format-buffer "Format Buffer"))))
|
||||||
|
|
||||||
(call-interactively 'lsp))
|
|
||||||
|
|
||||||
(use-package lsp-mode
|
|
||||||
:config
|
|
||||||
(major-mode-hydra-define+ python-mode (:quit-key "q")
|
(major-mode-hydra-define+ python-mode (:quit-key "q")
|
||||||
("Server"
|
("Server"
|
||||||
(("L" ha-setup-python-lsp "Start LSP Server")))))
|
( ;; ("L" eglot-ensure "Start eglot") --> Not needed with eglot-ensure
|
||||||
|
("l" python-lsp/body "LSP...")))))
|
||||||
;; ----------------------------------------------------------------------
|
|
||||||
;; Missing Symbols to be integrated?
|
|
||||||
;; "0" '("treemacs" . lsp-treemacs-symbols)
|
|
||||||
;; "/" '("complete" . completion-at-point)
|
|
||||||
;; "k" '("check code" . python-check)
|
|
||||||
;; "Fb" '("un-blacklist folder" . lsp-workspace-blacklist-remove)
|
|
||||||
;; "hs" '("signature help" . lsp-signature-activate)
|
|
||||||
;; "tT" '("toggle treemacs integration" . lsp-treemacs-sync-mode)
|
|
||||||
;; "ta" '("toggle modeline code actions" . lsp-modeline-code-actions-mode)
|
|
||||||
;; "th" '("toggle highlighting" . lsp-toggle-symbol-highlight)
|
|
||||||
;; "tl" '("toggle lenses" . lsp-lens-mode)
|
|
||||||
;; "ts" '("toggle signature" . lsp-toggle-signature-auto-activate)
|
|
||||||
#+end_src
|
#+end_src
|
||||||
* Project Configuration
|
* Project Configuration
|
||||||
I work with a lot of projects with my team where I need to /configure/ the project such that LSP and my Emacs setup works. Let's suppose I could point a function at a project directory, and have it /set it up/:
|
I work with a lot of projects with my team where I need to /configure/ the project such that LSP and my Emacs setup works. Let's suppose I could point a function at a project directory, and have it /set it up/:
|
||||||
|
|
@ -541,17 +422,9 @@ I work with a lot of projects with my team where I need to /configure/ the proje
|
||||||
(shell-command "pipconf --local")
|
(shell-command "pipconf --local")
|
||||||
(shell-command "pip install --upgrade pip"))
|
(shell-command "pip install --upgrade pip"))
|
||||||
|
|
||||||
(message "Configuring pip for LSP")
|
(message "Configuring pip for eglot/pyright")
|
||||||
(with-temp-file "requirements-dev.txt"
|
(with-temp-file "requirements-dev.txt"
|
||||||
(insert "python-lsp-server[all]\n")
|
(insert "pyright\n"))
|
||||||
|
|
||||||
;; Let's install these extra packages individually ...
|
|
||||||
(insert "pyls-flake8\n")
|
|
||||||
;; (insert "pylsp-mypy")
|
|
||||||
;; (insert "pyls-isort")
|
|
||||||
;; (insert "python-lsp-black")
|
|
||||||
;; (insert "pyls-memestra")
|
|
||||||
(insert "pylsp-rope\n"))
|
|
||||||
(shell-command "pip install -r requirements-dev.txt")))
|
(shell-command "pip install -r requirements-dev.txt")))
|
||||||
#+end_src
|
#+end_src
|
||||||
* Major Mode Hydra
|
* Major Mode Hydra
|
||||||
|
|
|
||||||
|
|
@ -229,37 +229,6 @@ The [[https://github.com/r0man/ruby-test-mode][ruby-test-mode]] project aims a r
|
||||||
"t A" '("test all" . ruby-test-run)
|
"t A" '("test all" . ruby-test-run)
|
||||||
"t a" '("retest" . ruby-test-rerun)))
|
"t a" '("retest" . ruby-test-rerun)))
|
||||||
#+end_src
|
#+end_src
|
||||||
** Robe
|
|
||||||
The [[https://github.com/dgutov/robe][Robe project]] can be used instead of [[file:ha-programming.org::*Language Server Protocol (LSP) Integration][LSP]].
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(use-package robe
|
|
||||||
|
|
||||||
:config
|
|
||||||
(ha-local-leader 'ruby-mode-map
|
|
||||||
"w" '(:ignore t :which-key "robe")
|
|
||||||
"ws" '("start" . robe-start))
|
|
||||||
|
|
||||||
;; The following leader-like keys, are only available when I have
|
|
||||||
;; started LSP, and is an alternate to Command-m:
|
|
||||||
:general
|
|
||||||
(:states 'normal :keymaps 'robe-mode-map
|
|
||||||
", w r" '("restart" . lsp-reconnect)
|
|
||||||
", w b" '("events" . lsp-events-buffer)
|
|
||||||
", w e" '("errors" . lsp-stderr-buffer)
|
|
||||||
", w q" '("quit" . lsp-shutdown)
|
|
||||||
", w l" '("load file" . ruby-load-file)
|
|
||||||
|
|
||||||
", l r" '("rename" . lsp-rename)
|
|
||||||
", l f" '("format" . lsp-format)
|
|
||||||
", l a" '("actions" . lsp-code-actions)
|
|
||||||
", l i" '("imports" . lsp-code-action-organize-imports)
|
|
||||||
", l d" '("doc" . lsp-lookup-documentation)))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
Do we want to load Robe /automatically/?
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(use-package robe :hook (ruby-mode . robe-mode))
|
|
||||||
#+end_src
|
|
||||||
** Bundler
|
** Bundler
|
||||||
The [[https://github.com/endofunky/bundler.el][Bundler project]] integrates [[https://bundler.io/][bundler]] to install a projects Gems.
|
The [[https://github.com/endofunky/bundler.el][Bundler project]] integrates [[https://bundler.io/][bundler]] to install a projects Gems.
|
||||||
|
|
||||||
|
|
@ -295,6 +264,34 @@ Seems that to understand and edit Cucumber /feature/ definitions, you need [[htt
|
||||||
** RSpec
|
** RSpec
|
||||||
https://github.com/pezra/rspec-mode
|
https://github.com/pezra/rspec-mode
|
||||||
* LSP
|
* LSP
|
||||||
|
The built-in Eglot package natively supports [[https://github.com/castwide/solargraph][Solargraph]] via =eglot-server-programs= (no extra package needed):
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package eglot
|
||||||
|
:straight nil
|
||||||
|
:after ruby-mode
|
||||||
|
:defer t
|
||||||
|
:hook (ruby-mode . eglot-ensure))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Keybindings for the eglot-based LSP sub-menu, wired into the =ruby-mode= local leader:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package eglot
|
||||||
|
:straight nil
|
||||||
|
:after ruby-mode
|
||||||
|
:config
|
||||||
|
(ha-local-leader 'ruby-mode-map
|
||||||
|
"w" '(:ignore t :which-key "eglot")
|
||||||
|
"wD" '("disconnect" . eglot-shutdown)
|
||||||
|
"wR" '("reconnect" . eglot-reconnect)
|
||||||
|
"w?" '("describe" . eglot-show-workspace-configuration)
|
||||||
|
"wa" '("code actions" . eglot-code-actions)
|
||||||
|
"wo" '("organize imports" . eglot-code-action-organize-imports)
|
||||||
|
"wr" '("rename" . eglot-rename)
|
||||||
|
"w=" '("format buffer" . eglot-format-buffer)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
Need to install [[https://github.com/castwide/solargraph][Solargraph]] for the LSP server experience:
|
Need to install [[https://github.com/castwide/solargraph][Solargraph]] for the LSP server experience:
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
gem install solargraph
|
gem install solargraph
|
||||||
|
|
@ -303,29 +300,7 @@ Or add it to your =Gemfile=:
|
||||||
#+begin_src ruby
|
#+begin_src ruby
|
||||||
gem 'solargraph', group: :development
|
gem 'solargraph', group: :development
|
||||||
#+end_src
|
#+end_src
|
||||||
* XRef Interface with GNU Global
|
Once installed, [[*eglot][eglot]] finds and talks to =solargraph= automatically; no further Emacs configuration is needed.
|
||||||
The [[http://www.gnu.org/software/global/][GNU Global]] has the ability to generate a tags file for large, multi-project Ruby code bases.
|
|
||||||
|
|
||||||
First, issue these two:
|
|
||||||
#+begin_src sh :dir ~/work/gourmet
|
|
||||||
find . -name .git | while read DOTGIT
|
|
||||||
do
|
|
||||||
REPO=$(dirname $DOTGIT)
|
|
||||||
(cd $REPO && git pull origin master)
|
|
||||||
done
|
|
||||||
|
|
||||||
find . -name "*.rb" > gtags.files
|
|
||||||
gtags --gtagslabel=new-ctags --file gtags.files
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
And now we need the GNU Global for Emacs, we are using the most up-to-date version of [[https://github.com/leoliu/ggtags][ggtags]].
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(use-package ggtags
|
|
||||||
:hook ((ruby-mode . #'ggtags-mode)))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
Careful observers will note that
|
|
||||||
* Technical Artifacts :noexport:
|
* Technical Artifacts :noexport:
|
||||||
|
|
||||||
Let's =provide= a name so we can =require= this file:
|
Let's =provide= a name so we can =require= this file:
|
||||||
|
|
|
||||||
|
|
@ -68,24 +68,10 @@ The [[https://github.com/brotzeit/rustic][rustic project]] incorporates [[https:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package rustic
|
(use-package rustic
|
||||||
:init
|
:config
|
||||||
(setq rustic-lsp-client 'eglot
|
(setq rustic-lsp-client 'eglot
|
||||||
rustic-analyzer-command '("/opt/homebrew/bin/rust-analyzer"))
|
rustic-analyzer-command '("/opt/homebrew/bin/rust-analyzer")
|
||||||
;; :bind (:map rustic-mode-map
|
rustic-format-on-save t))
|
||||||
;; ("M-j" . lsp-ui-imenu)
|
|
||||||
;; ("M-?" . lsp-find-references)
|
|
||||||
;; ("C-c C-c l" . flycheck-list-errors)
|
|
||||||
;; ("C-c C-c a" . lsp-execute-code-action)
|
|
||||||
;; ("C-c C-c r" . lsp-rename)
|
|
||||||
;; ("C-c C-c q" . lsp-workspace-restart)
|
|
||||||
;; ("C-c C-c Q" . lsp-workspace-shutdown)
|
|
||||||
;; ("C-c C-c s" . lsp-rust-analyzer-status)
|
|
||||||
;; ("C-c C-c e" . lsp-rust-analyzer-expand-macro)
|
|
||||||
;; ("C-c C-c d" . dap-hydra)
|
|
||||||
;; ("C-c C-c h" . lsp-ui-doc-glance))
|
|
||||||
|
|
||||||
:config
|
|
||||||
(setq rustic-format-on-save t))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** The Playground
|
** The Playground
|
||||||
|
|
@ -102,7 +88,6 @@ The [[https://github.com/dryman/toml-mode.el][toml-mode]] adds syntax highlighti
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package toml-mode)
|
(use-package toml-mode)
|
||||||
#+end_src
|
#+end_src
|
||||||
* LSP
|
|
||||||
* Technical Artifacts :noexport:
|
* Technical Artifacts :noexport:
|
||||||
Let's =provide= a name so we can =require= this file:
|
Let's =provide= a name so we can =require= this file:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -683,86 +683,21 @@ I have two different /jumping/ systems, the [[info:emacs#Xref][Xref interface]]
|
||||||
The [[https://microsoft.github.io/language-server-protocol/][LSP]] is a way to connect /editors/ (like Emacs) to /languages/ (like Lisp)… wait, no. While originally designed for VS Code and probably Python, we can abstract away [[https://github.com/davidhalter/jedi][Jedi]] and the [[http://tkf.github.io/emacs-jedi/latest/][Emacs integration to Jedi]] (and duplicate everything for Ruby, and Clojure, and…).
|
The [[https://microsoft.github.io/language-server-protocol/][LSP]] is a way to connect /editors/ (like Emacs) to /languages/ (like Lisp)… wait, no. While originally designed for VS Code and probably Python, we can abstract away [[https://github.com/davidhalter/jedi][Jedi]] and the [[http://tkf.github.io/emacs-jedi/latest/][Emacs integration to Jedi]] (and duplicate everything for Ruby, and Clojure, and…).
|
||||||
|
|
||||||
Emacs has two LSP projects, and while I have used [[LSP Mode]], but since I don’t have heavy IDE requirements, I am finding that [[eglot]] to be simpler.
|
Emacs has two LSP projects, and while I have used [[LSP Mode]], but since I don’t have heavy IDE requirements, I am finding that [[eglot]] to be simpler.
|
||||||
*** LSP
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package lsp-mode
|
(use-package eglot
|
||||||
:commands (lsp lsp-deferred)
|
:straight nil
|
||||||
:init
|
:commands eglot-ensure
|
||||||
;; Let's make lsp-doctor happy with these settings:
|
|
||||||
(setq gc-cons-threshold (* 100 1024 1024)
|
|
||||||
read-process-output-max (* 1024 1024)
|
|
||||||
company-idle-delay 0.0 ; Are thing fast enough to do this?
|
|
||||||
lsp-keymap-prefix "s-m")
|
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(global-set-key (kbd "s-m") 'lsp)
|
(setq eglot-autoshutdown t))
|
||||||
;; (ha-local-leader :keymaps 'prog-mode-map
|
|
||||||
;; "w" '(:ignore t :which-key "lsp")
|
|
||||||
;; "l" '(:ignore t :which-key "lsp")
|
|
||||||
;; "ws" '("start" . lsp))
|
|
||||||
|
|
||||||
;; ;; The following leader-like keys, are only available when I have
|
|
||||||
;; ;; started LSP, and is an alternate to Command-m:
|
|
||||||
;; :general
|
|
||||||
;; (:states 'normal :keymaps 'lsp-mode-map
|
|
||||||
;; ", w r" '("restart" . lsp-reconnect)
|
|
||||||
;; ", w b" '("events" . lsp-events-buffer)
|
|
||||||
;; ", w e" '("errors" . lsp-stderr-buffer)
|
|
||||||
;; ", w q" '("quit" . lsp-shutdown)
|
|
||||||
;; ", w Q" '("quit all" . lsp-shutdown-all)
|
|
||||||
|
|
||||||
;; ", l r" '("rename" . lsp-rename)
|
|
||||||
;; ", l f" '("format" . lsp-format)
|
|
||||||
;; ", l a" '("actions" . lsp-code-actions)
|
|
||||||
;; ", l i" '("imports" . lsp-code-action-organize-imports)
|
|
||||||
;; ", l d" '("doc" . lsp-lookup-documentation))
|
|
||||||
|
|
||||||
:hook ((lsp-mode . lsp-enable-which-key-integration)))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
I will want to start adding commands under my =,= mode-specific key sequence leader, but in the meantime, all LSP-related keybindings are available under ~⌘-m~. See [[https://emacs-lsp.github.io/lsp-mode/page/keybindings/][this page]] for the default keybindings.
|
|
||||||
|
|
||||||
Using the [[https://github.com/seagle0128/doom-modeline][Doom Modeline]] to add notifications:
|
The [[https://github.com/flycheck/flycheck-eglot][flycheck-eglot]] package bridges eglot diagnostics into flycheck, so existing checkers and keybindings continue to work unchanged:
|
||||||
#+begin_src emacs-lisp :tangle no
|
|
||||||
(use-package doom-modeline
|
|
||||||
:config
|
|
||||||
(setq doom-modeline-lsp t
|
|
||||||
doom-modeline-env-version t))
|
|
||||||
#+end_src
|
|
||||||
**** UI
|
|
||||||
The [[https://github.com/emacs-lsp/lsp-ui][lsp-ui]] project offers much of the display and interface to LSP. Seems to make the screen cluttered.
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package lsp-ui
|
(use-package flycheck-eglot
|
||||||
:commands lsp-ui-mode
|
:after (flycheck eglot)
|
||||||
:config
|
:config
|
||||||
(setq lsp-ui-sideline-ignore-duplicate t
|
(global-flycheck-eglot-mode 1))
|
||||||
lsp-ui-sideline-show-hover t
|
|
||||||
lsp-ui-sideline-show-diagnostics t)
|
|
||||||
:hook (lsp-mode . lsp-ui-mode))
|
|
||||||
#+end_src
|
|
||||||
*** Company Completion
|
|
||||||
The [[https://github.com/tigersoldier/company-lsp][company-lsp]] offers a [[http://company-mode.github.io/][company]] completion backend for [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]]:
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp :tangle no
|
|
||||||
(use-package company-lsp
|
|
||||||
:config
|
|
||||||
(push 'company-lsp company-backends))
|
|
||||||
#+end_src
|
|
||||||
To options that might be interesting:
|
|
||||||
- =company-lsp-async=: When set to non-nil, fetch completion candidates asynchronously.
|
|
||||||
- =company-lsp-enable-snippet=: Set it to non-nil if you want to enable snippet expansion on completion. Set it to nil to disable this feature.
|
|
||||||
|
|
||||||
*** LSP iMenu
|
|
||||||
The [[https://github.com/emacs-lsp/lsp-ui/blob/master/lsp-ui-imenu.el][lsp-imenu]] project offers a =lsp-ui-imenu= function for jumping to functions:
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp :tangle no
|
|
||||||
(use-package lsp-ui-imenu
|
|
||||||
:straight nil
|
|
||||||
:after lsp-ui
|
|
||||||
:config
|
|
||||||
(ha-local-leader :keymaps 'prog-mode-map
|
|
||||||
"g" '(:ignore t :which-key "goto")
|
|
||||||
"g m" '("imenu" . lsp-ui-imenu))
|
|
||||||
(add-hook 'lsp-after-open-hook 'lsp-enable-imenu))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
** General Code Editing
|
** General Code Editing
|
||||||
*** iEdit
|
*** iEdit
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,7 @@ Let’s make a /theme/:
|
||||||
`(mode-line ((t (:background ,active :foreground "white"))))
|
`(mode-line ((t (:background ,active :foreground "white"))))
|
||||||
`(mode-line-active ((t (:background ,active))))
|
`(mode-line-active ((t (:background ,active))))
|
||||||
`(mode-line-inactive ((t (:background ,inactive))))
|
`(mode-line-inactive ((t (:background ,inactive))))
|
||||||
|
`(which-func ((t (:foreground ,orange-lt))))
|
||||||
|
|
||||||
`(tab-bar ((t :foreground ,default-fg :background ,inactive :inherit variable-pitch)))
|
`(tab-bar ((t :foreground ,default-fg :background ,inactive :inherit variable-pitch)))
|
||||||
`(tab-line ((t :foreground ,default-fg :background ,inactive)))
|
`(tab-line ((t :foreground ,default-fg :background ,inactive)))
|
||||||
|
|
|
||||||
15
initialize
15
initialize
|
|
@ -31,7 +31,7 @@ cat > "$HAMACS_DEST/early-init.el" <<EOF
|
||||||
;; ███ █▄ ███ ███ ███ ███ ███ ███ █▄ ███
|
;; ███ █▄ ███ ███ ███ ███ ███ ███ █▄ ███
|
||||||
;; ███ ███ ███ ███ ███ ███ ███ ███ ███ ▄█ ███
|
;; ███ ███ ███ ███ ███ ███ ███ ███ ███ ▄█ ███
|
||||||
;; ██████████ ▀█ ███ █▀ ███ █▀ ████████▀ ▄████████▀
|
;; ██████████ ▀█ ███ █▀ ███ █▀ ████████▀ ▄████████▀
|
||||||
;;
|
;;
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;
|
;;
|
||||||
;; This is my early Emacs configuration file. See init.el for the real
|
;; This is my early Emacs configuration file. See init.el for the real
|
||||||
|
|
@ -85,7 +85,7 @@ cat > "$HAMACS_DEST/init.el" <<EOF
|
||||||
;; +#+ +#+ +#+ +#+ +#+ +#+ +#+
|
;; +#+ +#+ +#+ +#+ +#+ +#+ +#+
|
||||||
;; #+# #+# #+# #+# #+# #+# #+# #+# #+#
|
;; #+# #+# #+# #+# #+# #+# #+# #+# #+#
|
||||||
;; ########## ### ### ### ### ######## ########
|
;; ########## ### ### ### ### ######## ########
|
||||||
;;
|
;;
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;
|
;;
|
||||||
;; This is my Emacs Bootloader. Simply put, I initialize the package
|
;; This is my Emacs Bootloader. Simply put, I initialize the package
|
||||||
|
|
@ -135,7 +135,16 @@ cat > "$HAMACS_DEST/init.el" <<EOF
|
||||||
;; While that enables the :straight t extension to use-package, let's just have that be the default:
|
;; While that enables the :straight t extension to use-package, let's just have that be the default:
|
||||||
(use-package straight
|
(use-package straight
|
||||||
:custom (straight-use-package-by-default t
|
:custom (straight-use-package-by-default t
|
||||||
straight-default-vc 'git))
|
straight-default-vc 'git)
|
||||||
|
|
||||||
|
:init
|
||||||
|
;; Eglot and its dependencies ship with Emacs. Tell straight to treat them as
|
||||||
|
;; built-in so nothing (e.g. flycheck-eglot's dependency header) re-pulls the
|
||||||
|
;; GNU-ELPA copies, which would shadow the built-ins and trip eglot's
|
||||||
|
;; `require-with-check' ("Feature `project' is now provided by a different file").
|
||||||
|
(setq straight-built-in-pseudo-packages
|
||||||
|
(append '(eglot project flymake xref jsonrpc external-completion eldoc)
|
||||||
|
straight-built-in-pseudo-packages)))
|
||||||
|
|
||||||
;; See the details in https://dev.to/jkreeftmeijer/emacs-package-management-with-straight-el-and-use-package-3oc8
|
;; See the details in https://dev.to/jkreeftmeijer/emacs-package-management-with-straight-el-and-use-package-3oc8
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue