yeet
This commit is contained in:
139
.config/emacs/modules/lang/rust/README.org
Normal file
139
.config/emacs/modules/lang/rust/README.org
Normal file
@@ -0,0 +1,139 @@
|
||||
#+TITLE: lang/rust
|
||||
#+DATE: June 5, 2019
|
||||
#+SINCE: v3.0.0
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#hacks][Hacks]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#install][Install]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#general][General]]
|
||||
- [[#other-requirements][Other Requirements]]
|
||||
- [[#features][Features]]
|
||||
- [[#lsp-support-rls-or-rust-analyzer][LSP support (rls or rust-analyzer)]]
|
||||
- [[#format-on-save][Format on save]]
|
||||
- [[#keybinds][Keybinds]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#enable-rls-by-default][Enable RLS by default]]
|
||||
- [[#enabling-eglot-support-for-rust][Enabling eglot support for Rust]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
- [[#errore0670-async-fn-is-not-permitted-in-the-2015-edition][error[E0670]: `async fn` is not permitted in the 2015 edition]]
|
||||
|
||||
* Description
|
||||
This module adds support for the Rust language and integration for its tools,
|
||||
e.g. ~cargo~.
|
||||
|
||||
+ Code completion (=racer= or an LSP server)
|
||||
+ Syntax checking (=flycheck=)
|
||||
+ LSP support (for rust-analyzer and rls) (=rustic=)
|
||||
+ Snippets
|
||||
|
||||
** Module Flags
|
||||
+ ~+lsp~ to add support Language server protocol. Will use the first of
|
||||
=rust-analyzer= or =rls= (in that order).
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/brotzeit/rustic][rustic]]
|
||||
+ [[https://github.com/racer-rust/emacs-racer][racer]]* (unless =+lsp=)
|
||||
|
||||
** Hacks
|
||||
+ rustic has been modified /not/ to automatically install lsp-mode or eglot if
|
||||
they're missing. Doom expects you to have enabled the =:tools lsp= module
|
||||
yourself.
|
||||
|
||||
* Prerequisites
|
||||
|
||||
** Install
|
||||
|
||||
This module requires ~rust~, which can be acquired through =rustup=.
|
||||
|
||||
*** Arch Linux
|
||||
|
||||
#+begin_src sh
|
||||
sudo pacman -S rustup
|
||||
#+end_src
|
||||
|
||||
See also the Rust article [[https://wiki.archlinux.org/title/Rust#Rustup][on the Arch Wiki]].
|
||||
|
||||
Note that when the Rust /language/ has updates, you are to run =rustup= such that
|
||||
it doesn't upgrade itself:
|
||||
|
||||
#+begin_src sh
|
||||
rustup update --no-self-update
|
||||
#+end_src
|
||||
|
||||
*** General
|
||||
|
||||
#+begin_src sh
|
||||
curl https://sh.rustup.rs -sSf | sh
|
||||
#+end_src
|
||||
|
||||
** Other Requirements
|
||||
|
||||
Additional requirements depend on the module's configuration:
|
||||
|
||||
+ If =:editor format= is enabled, you'll need =rustfmt=: ~rustup component add
|
||||
rustfmt-preview~.
|
||||
+ Users without =+lsp= enabled will need =racer=: ~cargo +nightly install racer~
|
||||
(with requires rust nightly edition).
|
||||
+ Users with =+lsp= enabled will need:
|
||||
+ =rust-analyzer= or =rls=
|
||||
+ Using the following commands requires:
|
||||
+ ~cargo-process-check~: ~cargo install cargo-check~
|
||||
+ ~cargo-process-clippy~: ~rustup component add clippy-preview~
|
||||
|
||||
* Features
|
||||
** LSP support (rls or rust-analyzer)
|
||||
This module supports LSP integration. For it to work you'll need:
|
||||
|
||||
1. Either [[https://github.com/rust-analyzer/rust-analyzer][rust-analyzer]] or [[https://github.com/rust-lang/rls][the Rust Language Server]] installed (e.g. through your
|
||||
OS package manager).
|
||||
2. The =:tools lsp= module enabled.
|
||||
3. The ~+lsp~ flag on this module enabled.
|
||||
|
||||
** Format on save
|
||||
Enable the [[file:../../../modules/editor/format/README.org][:editor format]] module's =+onsave= flag to get formatting on save with
|
||||
rustfmt. No additional configuration is necessary.
|
||||
|
||||
** Keybinds
|
||||
| Binding | Description |
|
||||
|---------------------+-----------------------------|
|
||||
| ~<localleader> b a~ | ~cargo audit~ |
|
||||
| ~<localleader> b b~ | ~cargo build~ |
|
||||
| ~<localleader> b B~ | ~cargo bench~ |
|
||||
| ~<localleader> b c~ | ~cargo check~ |
|
||||
| ~<localleader> b C~ | ~cargo clippy~ |
|
||||
| ~<localleader> b d~ | ~cargo doc~ |
|
||||
| ~<localleader> b n~ | ~cargo update~ |
|
||||
| ~<localleader> b o~ | ~cargo outdated~ |
|
||||
| ~<localleader> b r~ | ~cargo run~ |
|
||||
| ~<localleader> t a~ | ~cargo test~ |
|
||||
| ~<localleader> t t~ | ~run current test~ |
|
||||
|
||||
* TODO Configuration
|
||||
** Enable RLS by default
|
||||
If both =rls= and =rust-analyzer= are present on your system, =rust-analyzer= is
|
||||
selected by default. Modify ~rustic-lsp-server~ to change the default:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;; in $DOOMDIR/config.el
|
||||
(after! rustic
|
||||
(setq rustic-lsp-server 'rls))
|
||||
#+END_SRC
|
||||
|
||||
** Enabling eglot support for Rust
|
||||
Doom's =:tools lsp= module has an =+eglot= flag. Enable it and this module will
|
||||
use eglot instead.
|
||||
|
||||
* Troubleshooting
|
||||
** error[E0670]: `async fn` is not permitted in the 2015 edition
|
||||
You may be seeing this error, despite having ~edition = "2018"~ in your
|
||||
=Cargo.toml=. This error actually originates from ~rustfmt~, which the LSP
|
||||
server tries to invoke on save (if you have ~rustic-format-on-save~ or =:editor
|
||||
format= enabled).
|
||||
|
||||
To fix this your project needs a =rustfmt.toml= with ~edition = "2018"~ in it.
|
||||
27
.config/emacs/modules/lang/rust/autoload.el
Normal file
27
.config/emacs/modules/lang/rust/autoload.el
Normal file
@@ -0,0 +1,27 @@
|
||||
;;; lang/rust/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; TODO (defun +rust/run-cargo () (interactive))
|
||||
|
||||
;;;###autoload
|
||||
(defun +rust-cargo-project-p ()
|
||||
"Return t if this is a cargo project."
|
||||
(locate-dominating-file buffer-file-name "Cargo.toml"))
|
||||
|
||||
;;;###autoload
|
||||
(defun +rust-racer-lookup-documentation (identifier)
|
||||
"A `+lookup/documentation' handler for Rust + Racer."
|
||||
(let ((buf (racer--describe identifier)))
|
||||
(when buf
|
||||
(pop-to-buffer buf)
|
||||
t)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Custom Cargo commands
|
||||
|
||||
(autoload 'rustic-run-cargo-command "rustic-cargo")
|
||||
;;;###autoload
|
||||
(defun +rust/cargo-audit ()
|
||||
"Run 'cargo audit' for the current project."
|
||||
(interactive)
|
||||
(rustic-run-cargo-command "cargo audit"))
|
||||
83
.config/emacs/modules/lang/rust/config.el
Normal file
83
.config/emacs/modules/lang/rust/config.el
Normal file
@@ -0,0 +1,83 @@
|
||||
;;; lang/rust/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! projectile
|
||||
(add-to-list 'projectile-project-root-files "Cargo.toml"))
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! rustic
|
||||
:mode ("\\.rs$" . rustic-mode)
|
||||
:init
|
||||
(after! org-src
|
||||
(defalias 'org-babel-execute:rust #'org-babel-execute:rustic)
|
||||
(add-to-list 'org-src-lang-modes '("rust" . rustic)))
|
||||
:config
|
||||
(setq rustic-indent-method-chain t)
|
||||
|
||||
(set-docsets! 'rustic-mode "Rust")
|
||||
(set-popup-rule! "^\\*rustic-compilation" :vslot -1)
|
||||
|
||||
;; Leave automatic reformatting to the :editor format module.
|
||||
(setq rustic-babel-format-src-block nil
|
||||
rustic-format-trigger nil)
|
||||
|
||||
;; HACK `rustic-flycheck' adds all these hooks in disruptive places. Instead,
|
||||
;; leave it to our :checkers syntax module to do all the set up properly.
|
||||
(remove-hook 'rustic-mode-hook #'flycheck-mode)
|
||||
(remove-hook 'rustic-mode-hook #'flymake-mode-off)
|
||||
(unless (featurep! +lsp)
|
||||
(after! flycheck
|
||||
(add-to-list 'flycheck-checkers 'rustic-clippy)))
|
||||
|
||||
;; HACK `rustic-lsp' sets up lsp-mode/eglot too early. We move it to
|
||||
;; `rustic-mode-local-vars-hook' so file/dir local variables can be used
|
||||
;; to reconfigure them.
|
||||
(when (featurep! +lsp)
|
||||
(remove-hook 'rustic-mode-hook #'rustic-setup-lsp)
|
||||
(add-hook 'rustic-mode-local-vars-hook #'rustic-setup-lsp)
|
||||
(setq rustic-lsp-client
|
||||
(if (featurep! :tools lsp +eglot)
|
||||
'eglot
|
||||
'lsp-mode)))
|
||||
|
||||
(map! :map rustic-mode-map
|
||||
:localleader
|
||||
(:prefix ("b" . "build")
|
||||
:desc "cargo audit" "a" #'+rust/cargo-audit
|
||||
:desc "cargo build" "b" #'rustic-cargo-build
|
||||
:desc "cargo bench" "B" #'rustic-cargo-bench
|
||||
:desc "cargo check" "c" #'rustic-cargo-check
|
||||
:desc "cargo clippy" "C" #'rustic-cargo-clippy
|
||||
:desc "cargo doc" "d" #'rustic-cargo-build-doc
|
||||
:desc "cargo doc --open" "D" #'rustic-cargo-doc
|
||||
:desc "cargo fmt" "f" #'rustic-cargo-fmt
|
||||
:desc "cargo new" "n" #'rustic-cargo-new
|
||||
:desc "cargo outdated" "o" #'rustic-cargo-outdated
|
||||
:desc "cargo run" "r" #'rustic-cargo-run)
|
||||
(:prefix ("t" . "cargo test")
|
||||
:desc "all" "a" #'rustic-cargo-test
|
||||
:desc "current test" "t" #'rustic-cargo-current-test))
|
||||
|
||||
;; If lsp/eglot isn't available, it attempts to install lsp-mode via
|
||||
;; package.el. Doom manages its own dependencies through straight so disable
|
||||
;; this behavior to avoid package-not-initialized errors.
|
||||
(defadvice! +rust--dont-install-packages-a (&rest _)
|
||||
:override #'rustic-install-lsp-client-p
|
||||
(message "No LSP server running")))
|
||||
|
||||
|
||||
(use-package! racer
|
||||
:unless (featurep! +lsp)
|
||||
:hook (rustic-mode-local-vars . racer-mode)
|
||||
:init
|
||||
;; HACK Fix #2132: `racer' depends on `rust-mode', which tries to modify
|
||||
;; `auto-mode-alist'. We make extra sure that doesn't stick, especially
|
||||
;; when a buffer is reverted, as it is after rustfmt is done with it.
|
||||
(after! rust-mode
|
||||
(setq auto-mode-alist (delete '("\\.rs\\'" . rust-mode) auto-mode-alist)))
|
||||
:config
|
||||
(set-lookup-handlers! 'rustic-mode
|
||||
:definition '(racer-find-definition :async t)
|
||||
:documentation '+rust-racer-lookup-documentation))
|
||||
29
.config/emacs/modules/lang/rust/doctor.el
Normal file
29
.config/emacs/modules/lang/rust/doctor.el
Normal file
@@ -0,0 +1,29 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/rust/doctor.el
|
||||
|
||||
(assert! (or (not (featurep! +lsp))
|
||||
(featurep! :tools lsp))
|
||||
"This module requires (:tools lsp)")
|
||||
|
||||
(unless (executable-find "rustc")
|
||||
(warn! "Couldn't find rustc binary"))
|
||||
|
||||
(unless (executable-find "cargo")
|
||||
(warn! "Couldn't find cargo binary"))
|
||||
|
||||
(if (featurep! +lsp)
|
||||
(when (require 'rustic nil t)
|
||||
(pcase rustic-lsp-server
|
||||
(`rust-analyzer
|
||||
(unless (executable-find "rust-analyzer")
|
||||
(warn! "Couldn't find rust analyzer (rust-analyzer)")))
|
||||
(`rls
|
||||
(unless (executable-find "rls")
|
||||
(warn! "Couldn't find rls")))))
|
||||
(when (require 'racer nil t)
|
||||
;; racer
|
||||
(unless (file-exists-p racer-cmd)
|
||||
(warn! "Couldn't find the racer binary at `racer-cmd'"))
|
||||
;; rust source code (rustup component add rust-src)
|
||||
(unless (file-directory-p racer-rust-src-path)
|
||||
(warn! "Couldn't find Rust's source code at RUST_SRC_PATH or `racer-rust-src-path'"))))
|
||||
6
.config/emacs/modules/lang/rust/packages.el
Normal file
6
.config/emacs/modules/lang/rust/packages.el
Normal file
@@ -0,0 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/rust/packages.el
|
||||
|
||||
(package! rustic :pin "804ebfe0295a6bf37870e06f84a8d35f55c9f1a6")
|
||||
(unless (featurep! +lsp)
|
||||
(package! racer :pin "1e63e98626737ea9b662d4a9b1ffd6842b1c648c"))
|
||||
Reference in New Issue
Block a user