@@ -70,34 +70,6 @@ When nil, `where' will be aligned with `fn' or `trait'."
70
70
:safe #'booleanp
71
71
:group 'rust-mode )
72
72
73
- (defcustom rust-format-on-save nil
74
- " Format future rust buffers before saving using rustfmt."
75
- :type 'boolean
76
- :safe #'booleanp
77
- :group 'rust-mode )
78
-
79
- (defcustom rust-format-show-buffer t
80
- " Show *rustfmt* buffer if formatting detected problems."
81
- :type 'boolean
82
- :safe #'booleanp
83
- :group 'rust-mode )
84
-
85
- (defcustom rust-format-goto-problem t
86
- " Jump to location of first detected problem when formatting buffer."
87
- :type 'boolean
88
- :safe #'booleanp
89
- :group 'rust-mode )
90
-
91
- (defcustom rust-rustfmt-bin " rustfmt"
92
- " Path to rustfmt executable."
93
- :type 'string
94
- :group 'rust-mode )
95
-
96
- (defcustom rust-rustfmt-switches '(" --edition" " 2018" )
97
- " Arguments to pass when invoking the `rustfmt' executable."
98
- :type '(repeat string)
99
- :group 'rust-mode )
100
-
101
73
(defcustom rust-cargo-bin " cargo"
102
74
" Path to cargo executable."
103
75
:type 'string
@@ -1608,314 +1580,6 @@ This is written mainly to be used as `end-of-defun-function' for Rust."
1608
1580
; ; There is no opening brace, so consider the whole buffer to be one "defun"
1609
1581
(goto-char (point-max ))))
1610
1582
1611
- ; ;; Formatting using rustfmt
1612
-
1613
- (defconst rust-rustfmt-buffername " *rustfmt*" )
1614
-
1615
- (defun rust--format-call (buf )
1616
- " Format BUF using rustfmt."
1617
- (with-current-buffer (get-buffer-create rust-rustfmt-buffername)
1618
- (view-mode +1 )
1619
- (let ((inhibit-read-only t ))
1620
- (erase-buffer )
1621
- (insert-buffer-substring buf)
1622
- (let* ((tmpf (make-temp-file " rustfmt" ))
1623
- (ret (apply 'call-process-region
1624
- (point-min )
1625
- (point-max )
1626
- rust-rustfmt-bin
1627
- t
1628
- `(t , tmpf )
1629
- nil
1630
- rust-rustfmt-switches)))
1631
- (unwind-protect
1632
- (cond
1633
- ((zerop ret)
1634
- (if (not (string= (buffer-string )
1635
- (with-current-buffer buf (buffer-string ))))
1636
- ; ; replace-buffer-contents was in emacs 26.1, but it
1637
- ; ; was broken for non-ASCII strings, so we need 26.2.
1638
- (if (and (fboundp 'replace-buffer-contents )
1639
- (version<= " 26.2" emacs-version))
1640
- (with-current-buffer buf
1641
- (replace-buffer-contents rust-rustfmt-buffername))
1642
- (copy-to-buffer buf (point-min ) (point-max ))))
1643
- (kill-buffer ))
1644
- ((= ret 3 )
1645
- (if (not (string= (buffer-string )
1646
- (with-current-buffer buf (buffer-string ))))
1647
- (copy-to-buffer buf (point-min ) (point-max )))
1648
- (erase-buffer )
1649
- (insert-file-contents tmpf)
1650
- (rust--format-fix-rustfmt-buffer (buffer-name buf))
1651
- (error " Rustfmt could not format some lines, see *rustfmt* buffer for details " ))
1652
- (t
1653
- (erase-buffer )
1654
- (insert-file-contents tmpf)
1655
- (rust--format-fix-rustfmt-buffer (buffer-name buf))
1656
- (error " Rustfmt failed, see *rustfmt* buffer for details " ))))
1657
- (delete-file tmpf)))))
1658
-
1659
- ; ; Since we run rustfmt through stdin we get <stdin> markers in the
1660
- ; ; output. This replaces them with the buffer name instead.
1661
- (defun rust--format-fix-rustfmt-buffer (buffer-name )
1662
- (with-current-buffer (get-buffer rust-rustfmt-buffername)
1663
- (let ((inhibit-read-only t ))
1664
- (goto-char (point-min ))
1665
- (while (re-search-forward " --> <stdin>:" nil t )
1666
- (replace-match (format " --> %s : " buffer-name)))
1667
- (while (re-search-forward " --> stdin:" nil t )
1668
- (replace-match (format " --> %s : " buffer-name))))))
1669
-
1670
- ; ; If rust-mode has been configured to navigate to source of the error
1671
- ; ; or display it, do so -- and return true. Otherwise return nil to
1672
- ; ; indicate nothing was done.
1673
- (defun rust--format-error-handler ()
1674
- (let ((ok nil ))
1675
- (when rust-format-show-buffer
1676
- (display-buffer (get-buffer rust-rustfmt-buffername))
1677
- (setq ok t ))
1678
- (when rust-format-goto-problem
1679
- (rust-goto-format-problem)
1680
- (setq ok t ))
1681
- ok))
1682
-
1683
- (defun rust-goto-format-problem ()
1684
- " Jumps to problem reported by rustfmt, if any.
1685
-
1686
- In case of multiple problems cycles through them. Displays the
1687
- rustfmt complain in the echo area."
1688
- (interactive )
1689
- ; ; This uses position in *rustfmt* buffer to know which is the next
1690
- ; ; error to jump to, and source: line in the buffer to figure which
1691
- ; ; buffer it is from.
1692
- (let ((rustfmt (get-buffer rust-rustfmt-buffername)))
1693
- (if (not rustfmt)
1694
- (message " No *rustfmt*, no problems. " )
1695
- (let ((target-buffer (with-current-buffer rustfmt
1696
- (save-excursion
1697
- (goto-char (point-min ))
1698
- (when (re-search-forward " --> \\ ([^:]+\\ ):" nil t )
1699
- (match-string 1 )))))
1700
- (target-point (with-current-buffer rustfmt
1701
- ; ; No save-excursion, this is how we cycle through!
1702
- (let ((regex " --> [^:]+:\\ ([0-9]+\\ ):\\ ([0-9]+\\ )" ))
1703
- (when (or (re-search-forward regex nil t )
1704
- (progn (goto-char (point-min ))
1705
- (re-search-forward regex nil t )))
1706
- (cons (string-to-number (match-string 1 ))
1707
- (string-to-number (match-string 2 )))))))
1708
- (target-problem (with-current-buffer rustfmt
1709
- (save-excursion
1710
- (when (re-search-backward " ^error:.+\n " nil t )
1711
- (forward-char (length " error: " ))
1712
- (let ((p0 (point )))
1713
- (if (re-search-forward " \n error:.+\n " nil t )
1714
- (buffer-substring p0 (point ))
1715
- (buffer-substring p0 (point-max )))))))))
1716
- (when (and target-buffer (get-buffer target-buffer) target-point)
1717
- (switch-to-buffer target-buffer)
1718
- (goto-char (point-min ))
1719
- (forward-line (1- (car target-point)))
1720
- (forward-char (1- (cdr target-point))))
1721
- (message target-problem)))))
1722
-
1723
- (defconst rust--format-word " \
1724
- \\ b\\ (else\\ |enum\\ |fn\\ |for\\ |if\\ |let\\ |loop\\ |\
1725
- match\\ |struct\\ |union\\ |unsafe\\ |while\\ )\\ b" )
1726
- (defconst rust--format-line " \\ ([\n ]\\ )" )
1727
-
1728
- ; ; Counts number of matches of regex beginning up to max-beginning,
1729
- ; ; leaving the point at the beginning of the last match.
1730
- (defun rust--format-count (regex max-beginning )
1731
- (let ((count 0 )
1732
- save-point
1733
- beginning)
1734
- (while (and (< (point ) max-beginning)
1735
- (re-search-forward regex max-beginning t ))
1736
- (setq count (1+ count))
1737
- (setq beginning (match-beginning 1 )))
1738
- ; ; try one more in case max-beginning lies in the middle of a match
1739
- (setq save-point (point ))
1740
- (when (re-search-forward regex nil t )
1741
- (let ((try-beginning (match-beginning 1 )))
1742
- (if (> try-beginning max-beginning)
1743
- (goto-char save-point)
1744
- (setq count (1+ count))
1745
- (setq beginning try-beginning))))
1746
- (when beginning (goto-char beginning))
1747
- count))
1748
-
1749
- ; ; Gets list describing pos or (point).
1750
- ; ; The list contains:
1751
- ; ; 1. the number of matches of rust--format-word,
1752
- ; ; 2. the number of matches of rust--format-line after that,
1753
- ; ; 3. the number of columns after that.
1754
- (defun rust--format-get-loc (buffer &optional pos )
1755
- (with-current-buffer buffer
1756
- (save-excursion
1757
- (let ((pos (or pos (point )))
1758
- words lines columns)
1759
- (goto-char (point-min ))
1760
- (setq words (rust--format-count rust--format-word pos))
1761
- (setq lines (rust--format-count rust--format-line pos))
1762
- (if (> lines 0 )
1763
- (if (= (point ) pos)
1764
- (setq columns -1 )
1765
- (forward-char 1 )
1766
- (goto-char pos)
1767
- (setq columns (current-column )))
1768
- (let ((initial-column (current-column )))
1769
- (goto-char pos)
1770
- (setq columns (- (current-column ) initial-column))))
1771
- (list words lines columns)))))
1772
-
1773
- ; ; Moves the point forward by count matches of regex up to max-pos,
1774
- ; ; and returns new max-pos making sure final position does not include another match.
1775
- (defun rust--format-forward (regex count max-pos )
1776
- (when (< (point ) max-pos)
1777
- (let ((beginning (point )))
1778
- (while (> count 0 )
1779
- (setq count (1- count))
1780
- (re-search-forward regex nil t )
1781
- (setq beginning (match-beginning 1 )))
1782
- (when (re-search-forward regex nil t )
1783
- (setq max-pos (min max-pos (match-beginning 1 ))))
1784
- (goto-char beginning)))
1785
- max-pos)
1786
-
1787
- ; ; Gets the position from a location list obtained using rust--format-get-loc.
1788
- (defun rust--format-get-pos (buffer loc )
1789
- (with-current-buffer buffer
1790
- (save-excursion
1791
- (goto-char (point-min ))
1792
- (let ((max-pos (point-max ))
1793
- (words (pop loc))
1794
- (lines (pop loc))
1795
- (columns (pop loc)))
1796
- (setq max-pos (rust--format-forward rust--format-word words max-pos))
1797
- (setq max-pos (rust--format-forward rust--format-line lines max-pos))
1798
- (when (> lines 0 ) (forward-char ))
1799
- (let ((initial-column (current-column ))
1800
- (save-point (point )))
1801
- (move-end-of-line nil )
1802
- (when (> (current-column ) (+ initial-column columns))
1803
- (goto-char save-point)
1804
- (forward-char columns)))
1805
- (min (point ) max-pos)))))
1806
-
1807
- (defun rust-format-diff-buffer ()
1808
- " Show diff to current buffer from rustfmt.
1809
-
1810
- Return the created process."
1811
- (interactive )
1812
- (unless (executable-find rust-rustfmt-bin)
1813
- (error " Could not locate executable \% s\" " rust-rustfmt-bin))
1814
- (let* ((buffer
1815
- (with-current-buffer
1816
- (get-buffer-create " *rustfmt-diff*" )
1817
- (let ((inhibit-read-only t ))
1818
- (erase-buffer ))
1819
- (current-buffer )))
1820
- (proc
1821
- (apply 'start-process
1822
- " rustfmt-diff"
1823
- buffer
1824
- rust-rustfmt-bin
1825
- " --check"
1826
- (cons (buffer-file-name )
1827
- rust-rustfmt-switches))))
1828
- (set-process-sentinel proc 'rust-format-diff-buffer-sentinel )
1829
- proc))
1830
-
1831
- (defun rust-format-diff-buffer-sentinel (process _e )
1832
- (when (eq 'exit (process-status process))
1833
- (if (> (process-exit-status process) 0 )
1834
- (with-current-buffer " *rustfmt-diff*"
1835
- (let ((inhibit-read-only t ))
1836
- (diff-mode ))
1837
- (pop-to-buffer (current-buffer )))
1838
- (message " rustfmt check passed. " ))))
1839
-
1840
- (defun rust--format-buffer-using-replace-buffer-contents ()
1841
- (condition-case err
1842
- (progn
1843
- (rust--format-call (current-buffer ))
1844
- (message " Formatted buffer with rustfmt. " ))
1845
- (error
1846
- (or (rust--format-error-handler)
1847
- (signal (car err) (cdr err))))))
1848
-
1849
- (defun rust--format-buffer-saving-position-manually ()
1850
- (let* ((current (current-buffer ))
1851
- (base (or (buffer-base-buffer current) current))
1852
- buffer-loc
1853
- window-loc)
1854
- (dolist (buffer (buffer-list ))
1855
- (when (or (eq buffer base)
1856
- (eq (buffer-base-buffer buffer) base))
1857
- (push (list buffer
1858
- (rust--format-get-loc buffer nil ))
1859
- buffer-loc)))
1860
- (dolist (frame (frame-list ))
1861
- (dolist (window (window-list frame))
1862
- (let ((buffer (window-buffer window)))
1863
- (when (or (eq buffer base)
1864
- (eq (buffer-base-buffer buffer) base))
1865
- (let ((start (window-start window))
1866
- (point (window-point window)))
1867
- (push (list window
1868
- (rust--format-get-loc buffer start)
1869
- (rust--format-get-loc buffer point))
1870
- window-loc))))))
1871
- (condition-case err
1872
- (unwind-protect
1873
- ; ; save and restore window start position
1874
- ; ; after reformatting
1875
- ; ; to avoid the disturbing scrolling
1876
- (let ((w-start (window-start )))
1877
- (rust--format-call (current-buffer ))
1878
- (set-window-start (selected-window ) w-start)
1879
- (message " Formatted buffer with rustfmt. " ))
1880
- (dolist (loc buffer-loc)
1881
- (let* ((buffer (pop loc))
1882
- (pos (rust--format-get-pos buffer (pop loc))))
1883
- (with-current-buffer buffer
1884
- (goto-char pos))))
1885
- (dolist (loc window-loc)
1886
- (let* ((window (pop loc))
1887
- (buffer (window-buffer window))
1888
- (start (rust--format-get-pos buffer (pop loc)))
1889
- (pos (rust--format-get-pos buffer (pop loc))))
1890
- (unless (eq buffer current)
1891
- (set-window-start window start))
1892
- (set-window-point window pos))))
1893
- (error
1894
- (or (rust--format-error-handler)
1895
- (signal (car err) (cdr err)))))))
1896
-
1897
- (defun rust-format-buffer ()
1898
- " Format the current buffer using rustfmt."
1899
- (interactive )
1900
- (unless (executable-find rust-rustfmt-bin)
1901
- (error " Could not locate executable \" %s \" " rust-rustfmt-bin))
1902
- ; ; If emacs version >= 26.2, we can use replace-buffer-contents to
1903
- ; ; preserve location and markers in buffer, otherwise we can try to
1904
- ; ; save locations as best we can, though we still lose markers.
1905
- (if (version<= " 26.2" emacs-version)
1906
- (rust--format-buffer-using-replace-buffer-contents)
1907
- (rust--format-buffer-saving-position-manually)))
1908
-
1909
- (defun rust-enable-format-on-save ()
1910
- " Enable formatting using rustfmt when saving buffer."
1911
- (interactive )
1912
- (setq-local rust-format-on-save t ))
1913
-
1914
- (defun rust-disable-format-on-save ()
1915
- " Disable formatting using rustfmt when saving buffer."
1916
- (interactive )
1917
- (setq-local rust-format-on-save nil ))
1918
-
1919
1583
(defun rust--compile (format-string &rest args )
1920
1584
(when (null rust-buffer-project)
1921
1585
(rust-update-buffer-project))
@@ -1955,26 +1619,6 @@ Return the created process."
1955
1619
(interactive )
1956
1620
(rust--compile " %s test" rust-cargo-bin))
1957
1621
1958
- ; ;; Hooks
1959
-
1960
- (defun rust-before-save-hook ()
1961
- (when rust-format-on-save
1962
- (condition-case e
1963
- (rust-format-buffer)
1964
- (error (format " rust-before-save-hook: %S %S "
1965
- (car e)
1966
- (cdr e))))))
1967
-
1968
- (defun rust-after-save-hook ()
1969
- (when rust-format-on-save
1970
- (if (not (executable-find rust-rustfmt-bin))
1971
- (error " Could not locate executable \" %s \" " rust-rustfmt-bin)
1972
- (when (get-buffer rust-rustfmt-buffername)
1973
- ; ; KLDUGE: re-run the error handlers -- otherwise message area
1974
- ; ; would show "Wrote ..." instead of the error description.
1975
- (or (rust--format-error-handler)
1976
- (message " rustfmt detected problems, see *rustfmt* for more. " ))))))
1977
-
1978
1622
; ;; Secondary Commands
1979
1623
1980
1624
(defun rust-playpen-region (begin end )
0 commit comments