diff --git a/IDE.org b/IDE.org index 5a2075a..e0c888f 100644 --- a/IDE.org +++ b/IDE.org @@ -15,10 +15,10 @@ (package-install-selected-packages :noconfirm) #+end_src -** Setup Rustic +** Setup Rustic :noexport: This is borrowed from https://robert.kra.hn/posts/rust-emacs-setup/ -#+begin_src emacs-lisp +#+begin_src emacs-lisp :tangle no (use-package rustic :ensure :bind (:map rustic-mode-map @@ -50,8 +50,8 @@ This is borrowed from https://robert.kra.hn/posts/rust-emacs-setup/ (add-hook 'before-save-hook 'lsp-format-buffer nil t)) #+end_src -** Setup LSP-mode and LSP-ui -#+begin_src emacs-lisp +** Setup LSP-mode and LSP-ui :noexport: +#+begin_src emacs-lisp :tangle no (use-package lsp-mode :ensure :commands lsp @@ -81,10 +81,68 @@ This is borrowed from https://robert.kra.hn/posts/rust-emacs-setup/ (lsp-ui-doc-enable nil)) #+end_src +** Rust-Mode with Eglot + +inspired by [[https://unwoundstack.com/blog/emacs-as-a-rust-ide.html][unwoundstack.com > Blog > Emacs as Rust IDE]] + +#+begin_src lisp :tangle ./modules/fschl-ide.el +(use-package smartparens :ensure t + :config (require 'smartparens-rust)) + +(defun sp1ff/rust/mode-hook () + "My rust-mode hook" + + (column-number-mode) + (display-line-numbers-mode) + (hs-minor-mode) + (smartparens-mode) + (define-key rust-mode-map "\C-ca" 'eglot-code-actions) + (define-key rust-mode-map (kbd "C-") 'sp-forward-slurp-sexp) + (define-key rust-mode-map (kbd "C-") 'sp-forward-barf-sexp) + (define-key rust-mode-map (kbd "C-M-") 'sp-backward-slurp-sexp) + (define-key rust-mode-map (kbd "C-M-") 'sp-backward-barf-sexp) + (define-key rust-mode-map "\C-c>" 'hs-show-all) + (define-key rust-mode-map "\C-c<" 'hs-hide-all) + (define-key rust-mode-map "\C-c-" 'hs-toggle-hiding) + (define-key rust-mode-map "\C-c+" 'hs-hide-level) + (setq indent-tabs-mode nil + tab-width 4 + c-basic-offset 4 + fill-column 100)) + +(use-package rust-mode + :ensure t + :hook (rust-mode . sp1ff/rust/mode-hook) + :config + (let ((dot-cargo-bin (expand-file-name "~/.cargo/bin/"))) + (setq rust-rustfmt-bin (concat dot-cargo-bin "rustfmt") + rust-cargo-bin (concat dot-cargo-bin "cargo") + rust-format-on-save t))) + +(use-package clippy-flymake + :vc (:url "https://git.sr.ht/~mgmarlow/clippy-flymake" :branch main) + :hook (rust-mode . clippy-flymake-setup-backend)) + +(defun clippy-flymake-manually-activate-flymake () + "Shim for working around eglot's tendency to suppress flymake backends." + (add-hook 'flymake-diagnostic-functions #'eglot-flymake-backend nil t) + (flymake-mode 1)) + +;; `eglot' by default will suppress all other flymake backends than its own +;; This workaround will +;; add `flymake-clippy' +(use-package eglot + :ensure t + :hook ((rust-mode . eglot-ensure) + (eglot-managed-mode . clippy-flymake-manually-activate-flymake)) + :config + (add-to-list 'eglot-stay-out-of 'flymake)) + #+end_src + ** Auto-completion lsp-mode integrates with company mode -#+begin_src emacs-lisp +#+begin_src emacs-lisp :tangle ./modules/fschl-ide.el (use-package company :ensure :custom diff --git a/modules/fschl-ide.el b/modules/fschl-ide.el index dcedc24..fdf33fa 100644 --- a/modules/fschl-ide.el +++ b/modules/fschl-ide.el @@ -8,63 +8,57 @@ (add-to-list 'package-selected-packages 'ob-rust) (package-install-selected-packages :noconfirm) -(use-package rustic - :ensure - :bind (:map rustic-mode-map - ("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)) +(use-package smartparens :ensure t + :config (require 'smartparens-rust)) + +(defun sp1ff/rust/mode-hook () + "My rust-mode hook" + + (column-number-mode) + (display-line-numbers-mode) + (hs-minor-mode) + (smartparens-mode) + (define-key rust-mode-map "\C-ca" 'eglot-code-actions) + (define-key rust-mode-map (kbd "C-") 'sp-forward-slurp-sexp) + (define-key rust-mode-map (kbd "C-") 'sp-forward-barf-sexp) + (define-key rust-mode-map (kbd "C-M-") 'sp-backward-slurp-sexp) + (define-key rust-mode-map (kbd "C-M-") 'sp-backward-barf-sexp) + (define-key rust-mode-map "\C-c>" 'hs-show-all) + (define-key rust-mode-map "\C-c<" 'hs-hide-all) + (define-key rust-mode-map "\C-c-" 'hs-toggle-hiding) + (define-key rust-mode-map "\C-c+" 'hs-hide-level) + (setq indent-tabs-mode nil + tab-width 4 + c-basic-offset 4 + fill-column 100)) + +(use-package rust-mode + :ensure t + :hook (rust-mode . sp1ff/rust/mode-hook) :config - ;; uncomment for less flashiness - ;; (setq lsp-eldoc-hook nil) - ;; (setq lsp-enable-symbol-highlighting nil) - ;; (setq lsp-signature-auto-activate nil) + (let ((dot-cargo-bin (expand-file-name "~/.cargo/bin/"))) + (setq rust-rustfmt-bin (concat dot-cargo-bin "rustfmt") + rust-cargo-bin (concat dot-cargo-bin "cargo") + rust-format-on-save t))) - ;; comment to disable rustfmt on save - (setq rustic-format-on-save t) - (add-hook 'rustic-mode-hook 'rk/rustic-mode-hook)) +(use-package clippy-flymake + :vc (:url "https://git.sr.ht/~mgmarlow/clippy-flymake" :branch main) + :hook (rust-mode . clippy-flymake-setup-backend)) -(defun rk/rustic-mode-hook () - ;; so that run C-c C-c C-r works without having to confirm, but don't try to - ;; save rust buffers that are not file visiting. Once - ;; https://github.com/brotzeit/rustic/issues/253 has been resolved this should - ;; no longer be necessary. - (when buffer-file-name - (setq-local buffer-save-without-query t)) - (add-hook 'before-save-hook 'lsp-format-buffer nil t)) +(defun clippy-flymake-manually-activate-flymake () + "Shim for working around eglot's tendency to suppress flymake backends." + (add-hook 'flymake-diagnostic-functions #'eglot-flymake-backend nil t) + (flymake-mode 1)) -(use-package lsp-mode - :ensure - :commands lsp - :custom - ;; what to use when checking on-save. "check" is default, I prefer clippy - (lsp-rust-analyzer-cargo-watch-command "clippy") - (lsp-eldoc-render-all t) - (lsp-idle-delay 0.6) - ;; enable / disable the hints as you prefer: - (lsp-inlay-hint-enable t) - ;; These are optional configurations. See https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/#lsp-rust-analyzer-display-chaining-hints for a full list - (lsp-rust-analyzer-display-lifetime-elision-hints-enable "skip_trivial") - (lsp-rust-analyzer-display-chaining-hints t) - (lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names nil) - (lsp-rust-analyzer-display-closure-return-type-hints t) - (lsp-rust-analyzer-display-parameter-hints nil) - (lsp-rust-analyzer-display-reborrow-hints nil) +;; `eglot' by default will suppress all other flymake backends than its own +;; This workaround will +;; add `flymake-clippy' +(use-package eglot + :ensure t + :hook ((rust-mode . eglot-ensure) + (eglot-managed-mode . clippy-flymake-manually-activate-flymake)) :config - (add-hook 'lsp-mode-hook 'lsp-ui-mode)) - -(use-package lsp-ui - :ensure - :commands lsp-ui-mode - :custom - (lsp-ui-peek-always-show t) - (lsp-ui-sideline-show-hover t) - (lsp-ui-doc-enable nil)) + (add-to-list 'eglot-stay-out-of 'flymake)) (use-package company :ensure