Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provide alternative rust-mode that derives from rust-ts-mode #482

Merged
merged 2 commits into from
Feb 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
- [Clippy](#clippy)
- [Easy insertion of dbg!](#easy-insertion-of-dbg)
- [More commands](#more-commands)
- [highlighting with tree-sitter](#highlighting-with-tree-sitter)
- [tree-sitter](#tree-sitter)
- [LSP](#lsp)
- [eglot](#eglot)
- [lsp-mode](#lsp-mode)
Expand Down Expand Up @@ -191,9 +191,20 @@ This is bound to <kbd>C-c C-d</kbd> by default.

- `rust-toggle-mutability` toggle mut for var defined at current line

## highlighting with tree-sitter
## tree-sitter

You should take a look at [tree-sitter](https://github.com/emacs-tree-sitter/elisp-tree-sitter). When the dependencies are installed you can activate the feature with:
You can try the new native treesitter mode `rust-ts-mode` with:

```elisp
(use-package rust-mode
:init
(setq rust-mode-treesitter-derive t))
```

In case you want to use treesitter but can't use Emacs 29.1, you can
take a look at
[tree-sitter](https://github.com/emacs-tree-sitter/elisp-tree-sitter). When
the dependencies are installed you can activate the feature with:

```elisp
(use-package tree-sitter
Expand Down
22 changes: 22 additions & 0 deletions rust-mode-treesitter.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
;;; rust-mode-treesitter.el --- use native rust-ts-mode -*-lexical-binding: t-*-
;;; Commentary:

;; Derive from rust-ts-mode instead of prog-mode

;;; Code:

;;;###autoload
(require 'treesit)
(require 'rust-ts-mode)

(define-derived-mode rust-mode rust-ts-mode "Rust"
"Major mode for Rust code.

\\{rust-mode-map}"
:group 'rust-mode

(add-hook 'before-save-hook rust-before-save-hook nil t)
(add-hook 'after-save-hook rust-after-save-hook nil t))

(provide 'rust-mode-treesitter)
;;; rust-mode-treesitter.el ends here
70 changes: 10 additions & 60 deletions rust-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ to the function arguments. When nil, `->' will be indented one level."
:group 'rust-mode
:safe #'booleanp)

(defcustom rust-mode-treesitter-derive nil
"Whether rust-mode should derive from the new treesitter mode `rust-ts-mode'
instead of `prog-mode'. This option requires emacs29+."
:version "29.1"
:type 'boolean
:group 'rustic)

;;; Faces

(define-obsolete-face-alias 'rust-unsafe-face
Expand Down Expand Up @@ -250,66 +257,9 @@ See `prettify-symbols-compose-predicate'."
map)
"Keymap for Rust major mode.")

;;;###autoload
(define-derived-mode rust-mode prog-mode "Rust"
"Major mode for Rust code.

\\{rust-mode-map}"
:group 'rust-mode
:syntax-table rust-mode-syntax-table

;; Syntax
(setq-local syntax-propertize-function #'rust-syntax-propertize)

;; Indentation
(setq-local indent-line-function 'rust-mode-indent-line)

;; Fonts
(setq-local font-lock-defaults
'(rust-font-lock-keywords
nil nil nil nil
(font-lock-syntactic-face-function
. rust-mode-syntactic-face-function)))

;; Misc
(setq-local comment-start "// ")
(setq-local comment-end "")
(setq-local open-paren-in-column-0-is-defun-start nil)

;; Auto indent on }
(setq-local electric-indent-chars
(cons ?} (and (boundp 'electric-indent-chars)
electric-indent-chars)))

;; Allow paragraph fills for comments
(setq-local comment-start-skip "\\(?://[/!]*\\|/\\*[*!]?\\)[[:space:]]*")
(setq-local paragraph-start
(concat "[[:space:]]*\\(?:"
comment-start-skip
"\\|\\*/?[[:space:]]*\\|\\)$"))
(setq-local paragraph-separate paragraph-start)
(setq-local normal-auto-fill-function #'rust-do-auto-fill)
(setq-local fill-paragraph-function #'rust-fill-paragraph)
(setq-local fill-forward-paragraph-function #'rust-fill-forward-paragraph)
(setq-local adaptive-fill-function #'rust-find-fill-prefix)
(setq-local adaptive-fill-first-line-regexp "")
(setq-local comment-multi-line t)
(setq-local comment-line-break-function #'rust-comment-indent-new-line)
(setq-local imenu-generic-expression rust-imenu-generic-expression)
(setq-local imenu-syntax-alist '((?! . "w"))) ; For macro_rules!
(setq-local beginning-of-defun-function #'rust-beginning-of-defun)
(setq-local end-of-defun-function #'rust-end-of-defun)
(setq-local parse-sexp-lookup-properties t)
(setq-local electric-pair-inhibit-predicate
#'rust-electric-pair-inhibit-predicate-wrap)
(add-function :before-until (local 'electric-pair-skip-self)
#'rust-electric-pair-skip-self)
;; Configure prettify
(setq prettify-symbols-alist rust-prettify-symbols-alist)
(setq prettify-symbols-compose-predicate #'rust--prettify-symbols-compose-p)

(add-hook 'before-save-hook rust-before-save-hook nil t)
(add-hook 'after-save-hook rust-after-save-hook nil t))
(if (and (version<= "29.1" emacs-version) rust-mode-treesitter-derive)
(require 'rust-mode-treesitter)
(require 'rust-prog-mode))

;;;###autoload
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))
Expand Down
70 changes: 70 additions & 0 deletions rust-prog-mode.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
;;; rust-prog-mode.el --- old rust-mode without treesitter -*-lexical-binding: t-*-
;;; Commentary:

;; rust-mode code deriving from prog-mode instead of rust-ts-mode

;;; Code:

;;;###autoload
(define-derived-mode rust-mode prog-mode "Rust"
"Major mode for Rust code.

\\{rust-mode-map}"
:group 'rust-mode
:syntax-table rust-mode-syntax-table

;; Syntax
(setq-local syntax-propertize-function #'rust-syntax-propertize)

;; Indentation
(setq-local indent-line-function 'rust-mode-indent-line)

;; Fonts
(setq-local font-lock-defaults
'(rust-font-lock-keywords
nil nil nil nil
(font-lock-syntactic-face-function
. rust-mode-syntactic-face-function)))

;; Misc
(setq-local comment-start "// ")
(setq-local comment-end "")
(setq-local open-paren-in-column-0-is-defun-start nil)

;; Auto indent on }
(setq-local electric-indent-chars
(cons ?} (and (boundp 'electric-indent-chars)
electric-indent-chars)))

;; Allow paragraph fills for comments
(setq-local comment-start-skip "\\(?://[/!]*\\|/\\*[*!]?\\)[[:space:]]*")
(setq-local paragraph-start
(concat "[[:space:]]*\\(?:"
comment-start-skip
"\\|\\*/?[[:space:]]*\\|\\)$"))
(setq-local paragraph-separate paragraph-start)
(setq-local normal-auto-fill-function #'rust-do-auto-fill)
(setq-local fill-paragraph-function #'rust-fill-paragraph)
(setq-local fill-forward-paragraph-function #'rust-fill-forward-paragraph)
(setq-local adaptive-fill-function #'rust-find-fill-prefix)
(setq-local adaptive-fill-first-line-regexp "")
(setq-local comment-multi-line t)
(setq-local comment-line-break-function #'rust-comment-indent-new-line)
(setq-local imenu-generic-expression rust-imenu-generic-expression)
(setq-local imenu-syntax-alist '((?! . "w"))) ; For macro_rules!
(setq-local beginning-of-defun-function #'rust-beginning-of-defun)
(setq-local end-of-defun-function #'rust-end-of-defun)
(setq-local parse-sexp-lookup-properties t)
(setq-local electric-pair-inhibit-predicate
#'rust-electric-pair-inhibit-predicate-wrap)
(add-function :before-until (local 'electric-pair-skip-self)
#'rust-electric-pair-skip-self)
;; Configure prettify
(setq prettify-symbols-alist rust-prettify-symbols-alist)
(setq prettify-symbols-compose-predicate #'rust--prettify-symbols-compose-p)

(add-hook 'before-save-hook rust-before-save-hook nil t)
(add-hook 'after-save-hook rust-after-save-hook nil t))

(provide 'rust-prog-mode)
;;; rust-prog-mode.el ends here
Loading