@@ -409,6 +409,18 @@ not require any shell-side configuration. See
409
409
:type 'boolean
410
410
:group 'vterm )
411
411
412
+ (defcustom vterm-copy-mode-remove-fake-newlines nil
413
+ " When not-nil fake newlines are removed on entering copy mode.
414
+
415
+ vterm inserts \\= 'fake\\= ' newlines purely for rendering. When using
416
+ vterm-copy-mode these are in conflict with many emacs functions
417
+ like isearch-forward. if this varialbe is not-nil the
418
+ fake-newlines are removed on entering copy-mode and re-inserted
419
+ on leaving copy mode. Also truncate-lines is set to t on entering
420
+ copy-mode and set to nil on leaving."
421
+ :type 'boolean
422
+ :group 'vterm )
423
+
412
424
; ;; Faces
413
425
414
426
(defface vterm-color-black
@@ -506,6 +518,8 @@ Only background is used."
506
518
(defvar-local vterm--delete-char-function (symbol-function #'delete-char ))
507
519
(defvar-local vterm--delete-region-function (symbol-function #'delete-region ))
508
520
(defvar-local vterm--undecoded-bytes nil )
521
+ (defvar-local vterm--copy-mode-fake-newlines nil )
522
+
509
523
510
524
(defvar vterm-timer-delay 0.1
511
525
" Delay for refreshing the buffer after receiving updates from libvterm.
@@ -833,6 +847,24 @@ Optional argument RESET clears all the errors."
833
847
834
848
; ;; Copy Mode
835
849
850
+ (defun vterm--enter-copy-mode ()
851
+ (use-local-map nil )
852
+ (vterm-send-stop)
853
+ (when vterm-copy-mode-remove-fake-newlines
854
+ (save-excursion
855
+ (setq truncate-lines nil )
856
+ (vterm--remove-fake-newlines t ))))
857
+
858
+
859
+ (defun vterm--exit-copy-mode ()
860
+ (when vterm-copy-mode-remove-fake-newlines
861
+ (save-excursion
862
+ (setq truncate-lines t )
863
+ (vterm--reinsert-fake-newlines)))
864
+ (vterm-reset-cursor-point)
865
+ (use-local-map vterm-mode-map)
866
+ (vterm-send-start))
867
+
836
868
(define-minor-mode vterm-copy-mode
837
869
" Toggle `vterm-copy-mode' .
838
870
@@ -849,12 +881,8 @@ A conventient way to exit `vterm-copy-mode' is with
849
881
:keymap vterm-copy-mode-map
850
882
(if (equal major-mode 'vterm-mode )
851
883
(if vterm-copy-mode
852
- (progn ; enable vterm-copy-mode
853
- (use-local-map nil )
854
- (vterm-send-stop))
855
- (vterm-reset-cursor-point)
856
- (use-local-map vterm-mode-map)
857
- (vterm-send-start))
884
+ (vterm--enter-copy-mode)
885
+ (vterm--exit-copy-mode))
858
886
(user-error " You cannot enable vterm-copy-mode outside vterm buffers" )))
859
887
860
888
(defun vterm-copy-mode-done (arg )
@@ -1732,26 +1760,57 @@ Effectively toggle between the two positions."
1732
1760
(save-excursion
1733
1761
(vterm-reset-cursor-point))))
1734
1762
1735
- (defun vterm--remove-fake-newlines ()
1763
+ (defun vterm--reinsert-fake-newlines ()
1764
+ " Reinsert fake newline from `vterm--copy-mode-fake-newlines' ."
1765
+ (let ((inhibit-read-only t )
1766
+ (inhibit-redisplay t )
1767
+ (fake-newline-text " \n " )
1768
+ fake-newline-pos)
1769
+ (add-text-properties 0 1 '(vterm-line-wrap t rear-nonsticky t )
1770
+ fake-newline-text)
1771
+ (while vterm--copy-mode-fake-newlines
1772
+ (setq fake-newline-pos (car vterm--copy-mode-fake-newlines))
1773
+ (setq vterm--copy-mode-fake-newlines (cdr vterm--copy-mode-fake-newlines))
1774
+ (goto-char fake-newline-pos)
1775
+ (insert fake-newline-text))))
1776
+
1777
+ (defun vterm--remove-fake-newlines (&optional remembering-pos-p )
1736
1778
" Filter out injected newlines were injected when rendering the terminal.
1737
1779
1738
1780
These newlines were tagged with \\= 'vterm-line-wrap property so we
1739
- can find them and remove them."
1740
- (goto-char (point-min ))
1741
- (let (fake-newline)
1742
- (while (setq fake-newline (next-single-property-change (point )
1743
- 'vterm-line-wrap ))
1744
- (goto-char fake-newline)
1745
- (cl-assert (eq ?\n (char-after )))
1746
- (let ((inhibit-read-only t ))
1747
- (vterm--delete-char 1 )))))
1781
+ can find them and remove them.
1782
+ If REMEMBERING-POS-P is not nil remembering their positions in a buffer-local
1783
+ `vterm--copy-mode-fake-newlines' ."
1784
+ (let (fake-newline
1785
+ (inhibit-read-only t )
1786
+ (inhibit-redisplay t ))
1787
+ (when remembering-pos-p
1788
+ (setq vterm--copy-mode-fake-newlines nil ))
1748
1789
1790
+ (goto-char (point-max ))
1791
+ (when (and (bolp )
1792
+ (get-text-property (1- (point )) 'vterm-line-wrap ))
1793
+ (forward-char -1 )
1794
+ (when remembering-pos-p
1795
+ (setq vterm--copy-mode-fake-newlines
1796
+ (cons (point ) vterm--copy-mode-fake-newlines)))
1797
+ (vterm--delete-char 1 ))
1798
+
1799
+ (while (and (not (bobp ))
1800
+ (setq fake-newline (previous-single-property-change
1801
+ (point ) 'vterm-line-wrap )))
1802
+ (goto-char (1- fake-newline))
1803
+ (cl-assert (eq ?\n (char-after )))
1804
+ (when remembering-pos-p
1805
+ (setq vterm--copy-mode-fake-newlines
1806
+ (cons (point ) vterm--copy-mode-fake-newlines)))
1807
+ (vterm--delete-char 1 ))))
1749
1808
1750
1809
(defun vterm--filter-buffer-substring (content )
1751
1810
" Filter string CONTENT of fake/injected newlines."
1752
1811
(with-temp-buffer
1753
1812
(vterm--insert content)
1754
- (vterm--remove-fake-newlines)
1813
+ (vterm--remove-fake-newlines nil )
1755
1814
(buffer-string )))
1756
1815
1757
1816
0 commit comments