diff --git a/README.md b/README.md index a4d5987c..bef37a1b 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,16 @@ rustfmt and most of the common cargo commands should work remotely. We are currently updating the code base. If you encounter any command that doesn't work remotely, please open an issue. +## TreeSitter + +You can try the new native treesitter mode `rust-ts-mode` with: + +```elisp +(use-package rustic + :init + (setq rustic-treesitter-derive t)) +``` + ## Compilation ![](https://raw.githubusercontent.com/brotzeit/rustic/master/img/compilation_buffer.png) diff --git a/rustic-rust-mode.el b/rustic-rust-mode.el new file mode 100644 index 00000000..57be6336 --- /dev/null +++ b/rustic-rust-mode.el @@ -0,0 +1,34 @@ +;;; rustic-rust-mode.el --- rust-mode related code -*-lexical-binding: t-*- +;;; Commentary: + +;; Deprecated code related to rust-mode + +;;; Code: + +(setq rust-load-optional-libraries nil) +(setq rust-before-save-hook #'rustic-before-save-hook) +(setq rust-after-save-hook #'rustic-after-save-hook) +(require 'rust-mode) + +;;; Define aliases for removed rustic functions + +(defvaralias 'rustic-indent-offset 'rust-indent-offset) +(defvaralias 'rustic-indent-method-chain 'rust-indent-method-chain) +(defvaralias 'rustic-indent-where-clause 'rust-indent-where-clause) +(defvaralias 'rustic-match-angle-brackets 'rust-match-angle-brackets) +(defvaralias 'rustic-indent-return-type-to-arguments 'rust-indent-return-type-to-arguments) +(defalias 'rustic-indent-line #'rust-mode-indent-line) +(defalias 'rustic-end-of-defun #'rust-end-of-defun) + +;;;###autoload +(define-derived-mode rustic-mode rust-mode "Rustic" + "Major mode for Rust code. + +\\{rustic-mode-map}" + :group 'rustic + + (when (bound-and-true-p rustic-cargo-auto-add-missing-dependencies) + (add-hook 'lsp-after-diagnostics-hook 'rustic-cargo-add-missing-dependencies-hook nil t))) + +(provide 'rustic-rust-mode) +;;; rustic-rust-mode.el ends here diff --git a/rustic-ts-mode.el b/rustic-ts-mode.el new file mode 100644 index 00000000..dd93f080 --- /dev/null +++ b/rustic-ts-mode.el @@ -0,0 +1,25 @@ +;;; rustic-ts-mode.el --- use native rust-ts-mode -*-lexical-binding: t-*- +;;; Commentary: + +;; Derive from rust-ts-mode instead of rust-mode + +;;; Code: + +;;; For the save hooks this is required +(require 'rustic-rustfmt) + + +;;;###autoload +(define-derived-mode rustic-mode rust-ts-mode "Rustic (TS)" + "Major mode for Rust code. + +\\{rustic-mode-map}" + :group 'rustic + + (when (bound-and-true-p rustic-cargo-auto-add-missing-dependencies) + (add-hook 'lsp-after-diagnostics-hook 'rustic-cargo-add-missing-dependencies-hook nil t)) + (add-hook 'before-save-hook 'rustic-before-save-hook nil t) + (add-hook 'after-save-hook 'rustic-after-save-hook nil t)) + +(provide 'rustic-ts-mode) +;;; rustic-ts-mode.el ends here diff --git a/rustic.el b/rustic.el index c3c58f3e..96e377cc 100644 --- a/rustic.el +++ b/rustic.el @@ -34,11 +34,8 @@ (require 'subr-x) (require 'dash) - -(setq rust-load-optional-libraries nil) -(setq rust-before-save-hook #'rustic-before-save-hook) -(setq rust-after-save-hook #'rustic-after-save-hook) -(require 'rust-mode) +(when (version<= "29.1" emacs-version) + (require 'treesit)) ;;; Customization @@ -47,16 +44,6 @@ :link '(url-link "https://www.rustic-lang.org/") :group 'languages) -;;; Define aliases for removed rustic functions - -(defvaralias 'rustic-indent-offset 'rust-indent-offset) -(defvaralias 'rustic-indent-method-chain 'rust-indent-method-chain) -(defvaralias 'rustic-indent-where-clause 'rust-indent-where-clause) -(defvaralias 'rustic-match-angle-brackets 'rust-match-angle-brackets) -(defvaralias 'rustic-indent-return-type-to-arguments 'rust-indent-return-type-to-arguments) -(defalias 'rustic-indent-line #'rust-mode-indent-line) -(defalias 'rustic-end-of-defun #'rust-end-of-defun) - ;;; workaround for with-temp-buffer not propagating the environment, as per ;;; https://github.com/magit/magit/pull/4169 (defmacro rustic--with-temp-process-buffer (&rest body) @@ -75,6 +62,14 @@ as for that macro." (setq-local exec-path ,e) ,@body)))) +(defcustom rustic-treesitter-derive nil + "Whether rustic should derive from the new treesitter mode +`rust-ts-mode'. If not, it derives from `rust-mode'. This option +requires emacs29+" + :version "29.1" + :type 'boolean + :group 'rustic) + ;;; Workspace (defvar-local rustic--buffer-workspace nil @@ -152,24 +147,18 @@ this variable." map) "Keymap for `rustic-mode'.") -;;;###autoload -(define-derived-mode rustic-mode rust-mode "Rustic" - "Major mode for Rust code. - -\\{rustic-mode-map}" - :group 'rustic +(defun activate-rustic-mode () + (if (and (version<= "29.1" emacs-version) rustic-treesitter-derive) + (if (treesit-ready-p 'rust t) + (require 'rustic-ts-mode) + (require 'rustic-rust-mode)) + (require 'rustic-rust-mode))) - (when (bound-and-true-p rustic-cargo-auto-add-missing-dependencies) - (add-hook 'lsp-after-diagnostics-hook 'rustic-cargo-add-missing-dependencies-hook nil t))) +(activate-rustic-mode) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.rs\\'" . rustic-mode)) -;; remove rust-mode from `auto-mode-alist' -(let ((mode '("\\.rs\\'" . rust-mode))) - (when (member mode auto-mode-alist) - (setq auto-mode-alist (remove mode auto-mode-alist)))) - ;;; envrc support ;; To support envrc, it is necessary to wrap any buffer creation code