From 4227c712db2a11302ec4eda0c5035fecc4e3e4d2 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Sun, 10 Nov 2024 15:15:42 +0100 Subject: Upgrade rust-mode and yasnippet --- .emacs.d/lisp/rust-cargo-tests.el | 19 +++++++++++ .emacs.d/lisp/rust-mode.el | 2 +- .emacs.d/lisp/rust-rustfmt.el | 51 ++++++++++++++++++++++++++--- .emacs.d/lisp/yasnippet.el | 67 ++++++++++++++++++++------------------- 4 files changed, 100 insertions(+), 39 deletions(-) (limited to '.emacs.d/lisp') diff --git a/.emacs.d/lisp/rust-cargo-tests.el b/.emacs.d/lisp/rust-cargo-tests.el index f49cba0..fe78ac7 100644 --- a/.emacs.d/lisp/rust-cargo-tests.el +++ b/.emacs.d/lisp/rust-cargo-tests.el @@ -1,5 +1,6 @@ ;;; rust-cargo-tests.el --- ERT tests for rust-cargo.el -*- lexical-binding: t; -*- (require 'rust-cargo) +(require 'rust-rustfmt) (require 'ert) (defun rust-test--wait-process-exit () @@ -51,3 +52,21 @@ (rust-test--send-process-string "1234\n") (rust-test--wait-process-exit) (should (rust-test--find-string "***run interactive: 1234"))))) + +(ert-deftest rust-test-rustfmt () + (skip-unless (executable-find "rustfmt")) + (rust-test--with-main-file-buffer + (let ((old-content (buffer-string)) + (ret (rust-format-buffer))) + (should (string= ret "Formatted buffer with rustfmt.")) + (should (string= old-content (buffer-string)))))) + +(ert-deftest rust-test-rustfmt-parsing-errors () + (skip-unless (executable-find "rustfmt")) + (with-temp-buffer + (insert "fn main() {") + (rust-format-buffer) + (with-current-buffer "*rustfmt*" + (should (eq major-mode 'rust-format-mode)) + (should (rust-test--find-string "error:"))) + (kill-buffer "*rustfmt*"))) diff --git a/.emacs.d/lisp/rust-mode.el b/.emacs.d/lisp/rust-mode.el index 8d38295..52c5242 100644 --- a/.emacs.d/lisp/rust-mode.el +++ b/.emacs.d/lisp/rust-mode.el @@ -1,6 +1,6 @@ ;;; rust-mode.el --- A major-mode for editing Rust source code -*-lexical-binding: t-*- -;; Version: 1.0.5 +;; Version: 1.0.6 ;; Author: Mozilla ;; Url: https://github.com/rust-lang/rust-mode ;; Keywords: languages diff --git a/.emacs.d/lisp/rust-rustfmt.el b/.emacs.d/lisp/rust-rustfmt.el index cab183c..04dce45 100644 --- a/.emacs.d/lisp/rust-rustfmt.el +++ b/.emacs.d/lisp/rust-rustfmt.el @@ -7,6 +7,9 @@ ;;; Code: ;;; Options +(require 'rust-compile) +(require 'compile) + (defcustom rust-format-on-save nil "Format future rust buffers before saving using rustfmt." :type 'boolean @@ -30,7 +33,7 @@ :type 'string :group 'rust-mode) -(defcustom rust-rustfmt-switches '("--edition" "2018") +(defcustom rust-rustfmt-switches '("--edition" "2021") "Arguments to pass when invoking the `rustfmt' executable." :type '(repeat string) :group 'rust-mode) @@ -39,6 +42,34 @@ (defconst rust-rustfmt-buffername "*rustfmt*") +(define-compilation-mode rust-format-mode "rust-format" + "Major mode for Rust compilation output." + + (setq-local compilation-error-regexp-alist-alist nil) + (add-to-list 'compilation-error-regexp-alist-alist + (cons 'rustc-refs rustc-refs-compilation-regexps)) + (add-to-list 'compilation-error-regexp-alist-alist + (cons 'rustc rustc-compilation-regexps)) + (add-to-list 'compilation-error-regexp-alist-alist + (cons 'rustc-colon rustc-colon-compilation-regexps)) + (add-to-list 'compilation-error-regexp-alist-alist + (cons 'cargo cargo-compilation-regexps)) + (add-to-list 'compilation-error-regexp-alist-alist + (cons 'rustc-panics rustc-panics-compilation-regexps)) + + (setq-local compilation-error-regexp-alist nil) + (add-to-list 'compilation-error-regexp-alist 'rustc-refs) + (add-to-list 'compilation-error-regexp-alist 'rustc) + (add-to-list 'compilation-error-regexp-alist 'rustc-colon) + (add-to-list 'compilation-error-regexp-alist 'cargo) + (add-to-list 'compilation-error-regexp-alist 'rustc-panics) + + (add-hook 'next-error-hook #'rustc-scroll-down-after-next-error) + + (if (or compilation-auto-jump-to-first-error + (eq compilation-scroll-output 'first-error)) + (set (make-local-variable 'compilation-auto-jump-to-next) t))) + (defun rust--format-call (buf) "Format BUF using rustfmt." (let ((path exec-path)) @@ -69,10 +100,20 @@ (with-current-buffer buf (replace-buffer-contents rust-rustfmt-buffername)) (copy-to-buffer buf (point-min) (point-max)))) - (let ((win (get-buffer-window rust-rustfmt-buffername))) - (if win - (quit-window t win) - (kill-buffer rust-rustfmt-buffername)))) + (let ((win (get-buffer-window rust-rustfmt-buffername))) + (if win + (quit-window t win) + (kill-buffer rust-rustfmt-buffername)))) + ((= ret 1) + (erase-buffer) + (insert-file-contents tmpf) + + (rust-format-mode) ;; render compilation errors in compilation-mode + (setq-local compile-command (format "%s %s" rust-rustfmt-bin (buffer-file-name buf))) + + (rust--format-fix-rustfmt-buffer (buffer-name buf)) + (error "Rustfmt failed because of parsing errors, see %s buffer for details" + rust-rustfmt-buffername)) ((= ret 3) (if (not (string= (buffer-string) (with-current-buffer buf (buffer-string)))) diff --git a/.emacs.d/lisp/yasnippet.el b/.emacs.d/lisp/yasnippet.el index 0d52a96..782c440 100644 --- a/.emacs.d/lisp/yasnippet.el +++ b/.emacs.d/lisp/yasnippet.el @@ -4128,39 +4128,40 @@ Returns the newly created snippet." (yas--letenv expand-env ;; Put a single undo action for the expanded snippet's ;; content. - (let ((buffer-undo-list t)) - (goto-char begin) - (if (> emacs-major-version 29) - ;; Don't use the workaround for CC-mode's cache, - ;; since it was presumably a bug in CC-mode, so either - ;; it's fixed already, or it should get fixed. - (progn - (insert content) - (narrow-to-region begin (point)) - (goto-char (point-min)) - (yas--snippet-parse-create snippet)) - ;; Call before and after change functions manually, - ;; otherwise cc-mode's cache can get messed up. Don't use - ;; `inhibit-modification-hooks' for that, that blocks - ;; overlay and text property hooks as well! FIXME: Maybe - ;; use `combine-change-calls'? (Requires Emacs 27+ though.) - (run-hook-with-args 'before-change-functions begin end) - (let ((before-change-functions nil) - (after-change-functions nil)) - ;; Some versions of cc-mode (might be the one with Emacs - ;; 24.3 only) fail when inserting snippet content in a - ;; narrowed buffer, so make sure to insert before - ;; narrowing. - (insert content) - (narrow-to-region begin (point)) - (goto-char (point-min)) - (yas--snippet-parse-create snippet)) - (run-hook-with-args 'after-change-functions - (point-min) (point-max) - (- end begin)))) - (when (listp buffer-undo-list) - (push (cons (point-min) (point-max)) - buffer-undo-list)) + (unwind-protect + (let ((buffer-undo-list t)) + (goto-char begin) + (if (> emacs-major-version 29) + ;; Don't use the workaround for CC-mode's cache, + ;; since it was presumably a bug in CC-mode, so either + ;; it's fixed already, or it should get fixed. + (progn + (insert content) + (narrow-to-region begin (point)) + (goto-char (point-min)) + (yas--snippet-parse-create snippet)) + ;; Call before and after change functions manually, + ;; otherwise cc-mode's cache can get messed up. Don't use + ;; `inhibit-modification-hooks' for that, that blocks + ;; overlay and text property hooks as well! FIXME: Maybe + ;; use `combine-change-calls'? (Requires Emacs 27+ though.) + (run-hook-with-args 'before-change-functions begin end) + (let ((before-change-functions nil) + (after-change-functions nil)) + ;; Some versions of cc-mode (might be the one with Emacs + ;; 24.3 only) fail when inserting snippet content in a + ;; narrowed buffer, so make sure to insert before + ;; narrowing. + (insert content) + (narrow-to-region begin (point)) + (goto-char (point-min)) + (yas--snippet-parse-create snippet)) + (run-hook-with-args 'after-change-functions + (point-min) (point-max) + (- end begin)))) + (when (listp buffer-undo-list) + (push (cons (point-min) (point-max)) + buffer-undo-list))) ;; Indent, collecting undo information normally. (yas--indent snippet) -- cgit v1.3