diff --git a/rustic-rustfmt.el b/rustic-rustfmt.el index 0564147d..244df393 100644 --- a/rustic-rustfmt.el +++ b/rustic-rustfmt.el @@ -105,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 @@ -190,6 +196,29 @@ and it's `cdr' is a list of arguments." (kill-buffer proc-buffer) (message "Workspace formatted with cargo-fmt."))))) +;;;###autoload +(defun rustic-format-region () + "Format the current active region using rustfmt. + +This operation requires a nightly version of rustfmt. +" + (interactive) + (unless (or (eq major-mode 'rustic-mode) + (eq major-mode 'rustic-macro-expansion-mode)) + (error "Not a rustic-mode buffer.")) + (let ((file (buffer-file-name (current-buffer))) + (start (+ 1 (count-lines 1 (region-beginning)))) + (len (- (count-lines (region-beginning) (region-end)) 1))) + (rustic-compilation-process-live t) + (rustic-format-start-process + 'rustic-format-file-sentinel + :buffer (current-buffer) + :command + (append (list rustic-cargo-bin "+nightly" "fmt" "--") + (rustic-compute-rustfmt-file-lines-args file + start + (+ start len)))))) + ;;;###autoload (defun rustic-format-buffer () "Format the current buffer using rustfmt. diff --git a/test/rustic-format-test.el b/test/rustic-format-test.el index 3fbf2e98..c7cc18f7 100644 --- a/test/rustic-format-test.el +++ b/test/rustic-format-test.el @@ -208,3 +208,20 @@ (revert-buffer t t) (should (string= (buffer-string) formatted-string))) (kill-buffer buffer1)))) + + +(ert-deftest rustic-test-format-file () + (let* ((string "fn main() \n{\nlet x = 1;\n}\n") + (formatted-string "fn main() \n{\n let x = 1;\n}\n") + (dir (rustic-babel-generate-project t)) + (main (expand-file-name "main.rs" (concat dir "/src"))) + (buf (get-buffer-create "test"))) + (with-current-buffer buf (write-file main)) + (write-region string nil main nil 0) + (goto-char 13) + (push-mark (buffer-end-position)) + (setq mark-active t) + (rustic-format-region) + (with-temp-buffer + (insert-file-contents main) + (should (string= (buffer-string) formatted-string)))))