Skip to content

Commit

Permalink
Merge pull request #258 from rbartlensky/feature/format-region
Browse files Browse the repository at this point in the history
Implement `rustic-format-region`.
  • Loading branch information
brotzeit authored Jul 19, 2021
2 parents 6ca73bb + 1628fcb commit 26c2e09
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
48 changes: 46 additions & 2 deletions rustic-rustfmt.el
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

(require 'rustic-cargo)

(declare-function project-root "project")
(if (version<= emacs-version "28.0")
(declare-function project-roots "project")
(declare-function project-root "project"))

;;; Options

Expand Down Expand Up @@ -103,6 +105,12 @@ and it's `cdr' is a list of arguments."
(push (format "%s=%s" key (if (booleanp val) (if val "true" "false") val)) args)
(push "--config" args)))))

(defun rustic-compute-rustfmt-file-lines-args (file start end)
"Compute the arguments to rustfmt to modify a particular region."
(list "--unstable-features"
"--file-lines"
(format "[{\"file\":\"%s\",\"range\":[%d,%d]}]" file start end)))

(defun rustic-format-sentinel (proc output)
"Sentinel for rustfmt processes when using stdin."
(ignore-errors
Expand Down Expand Up @@ -188,6 +196,40 @@ and it's `cdr' is a list of arguments."
(kill-buffer proc-buffer)
(message "Workspace formatted with cargo-fmt.")))))

(defun rustic--get-line-number (pos)
(let ((line-number 0))
(save-excursion
(goto-char pos)
(setq line-number (string-to-number (format-mode-line "%l"))))
line-number))

;;;###autoload
(defun rustic-format-region (begin end)
"Format the current active region using rustfmt.
This operation requires a nightly version of rustfmt.
"
(interactive "r")
(unless (or (eq major-mode 'rustic-mode)
(eq major-mode 'rustic-macro-expansion-mode))
(error "Not a rustic-mode buffer."))
(if (not (region-active-p)) (rustic-format-buffer)
(unless (equal (call-process "cargo" nil nil nil "+nightly") 0)
(error "Need nightly toolchain to format region."))
(let* ((buf (current-buffer))
(file (buffer-file-name buf))
(start (rustic--get-line-number begin))
(finish (rustic--get-line-number end)))
(rustic-compilation-process-live t)
(rustic-format-start-process
'rustic-format-file-sentinel
:buffer buf
:command
(append (list rustic-cargo-bin "+nightly" "fmt" "--")
(rustic-compute-rustfmt-file-lines-args file
start
finish))))))

;;;###autoload
(defun rustic-format-buffer ()
"Format the current buffer using rustfmt.
Expand Down Expand Up @@ -226,7 +268,9 @@ This is basically a wrapper around `project--buffer-list'."
(if (fboundp 'project--buffer-list)
(project--buffer-list pr)
;; Like the above function but for releases before Emacs 28.
(let ((root (project-root pr))
(let ((root (if (version<= emacs-version "28.0")
(car (project-roots pr))
(project-root pr)))
bufs)
(dolist (buf (buffer-list))
(let ((filename (or (buffer-file-name buf)
Expand Down
18 changes: 18 additions & 0 deletions test/rustic-format-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,21 @@
(revert-buffer t t)
(should (string= (buffer-string) formatted-string)))
(kill-buffer buffer1))))

(ert-deftest rustic-test-format-region ()
(let* ((buffer1 (get-buffer-create "b1"))
(string "fn main() {\n let x =\n 1;\n}")
(formatted-string "fn main() {\n let x = 1;\n}\n")
(dir (rustic-babel-generate-project t))
(main (expand-file-name "main.rs" (concat dir "/src")))
(default-directory dir))
(with-current-buffer buffer1
(insert string)
(write-file main)
(rustic-mode)
(goto-char 16)
(push-mark 34)
(setq mark-active t)
(rustic-format-region 16 34)
(sit-for 1)
(should (string= (buffer-string) formatted-string)))))

0 comments on commit 26c2e09

Please sign in to comment.