aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Shahid2019-01-20 19:08:17 -0500
committerStefan Monnier2019-02-24 15:45:01 -0500
commit467e6ccb85e89cbfaccb25bb392d24a0511044fc (patch)
treefa10d9f7e4b25b1e3ab70cf9ed6d8bde096a2df2
parent28f7e981c10cddd06b879a79ade214f273ba4498 (diff)
downloademacs-467e6ccb85e89cbfaccb25bb392d24a0511044fc.tar.gz
emacs-467e6ccb85e89cbfaccb25bb392d24a0511044fc.zip
Adjust line wrapping on window resize and killing text
* lisp/term.el (term-mode): Advice filter-buffer-substring-function to remove line unwrapping from killed text. (term-reset-size): Add or remove line unwrapping depending on the new terminal width. (term-suppress-hard-newline): Mark obsolete. (term-unwrap-line): Use text properties to be able to find the newlines later.
-rw-r--r--lisp/term.el56
1 files changed, 54 insertions, 2 deletions
diff --git a/lisp/term.el b/lisp/term.el
index f49777f94c2..fdcc39de722 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -545,6 +545,9 @@ This means text can automatically reflow if the window is resized."
545 :version "24.4" 545 :version "24.4"
546 :type 'boolean 546 :type 'boolean
547 :group 'term) 547 :group 'term)
548(make-obsolete-variable 'term-suppress-hard-newline nil
549 "27.1"
550 'set)
548 551
549;; Where gud-display-frame should put the debugging arrow. This is 552;; Where gud-display-frame should put the debugging arrow. This is
550;; set by the marker-filter, which scans the debugger's output for 553;; set by the marker-filter, which scans the debugger's output for
@@ -1117,6 +1120,9 @@ Entry to this mode runs the hooks on `term-mode-hook'."
1117 (set (make-local-variable 'font-lock-defaults) '(nil t)) 1120 (set (make-local-variable 'font-lock-defaults) '(nil t))
1118 1121
1119 (add-function :filter-return 1122 (add-function :filter-return
1123 (local 'filter-buffer-substring-function)
1124 #'term--filter-buffer-substring)
1125 (add-function :filter-return
1120 (local 'window-adjust-process-window-size-function) 1126 (local 'window-adjust-process-window-size-function)
1121 (lambda (size) 1127 (lambda (size)
1122 (when size 1128 (when size
@@ -1132,9 +1138,51 @@ Entry to this mode runs the hooks on `term-mode-hook'."
1132 (setq term-input-ring (make-ring term-input-ring-size))) 1138 (setq term-input-ring (make-ring term-input-ring-size)))
1133 (term-update-mode-line)) 1139 (term-update-mode-line))
1134 1140
1141(defun term--remove-fake-newlines ()
1142 (goto-char (point-min))
1143 (let (fake-newline)
1144 (while (setq fake-newline (next-single-property-change (point)
1145 'term-line-wrap))
1146 (goto-char fake-newline)
1147 (assert (eq ?\n (char-after)))
1148 (let ((inhibit-read-only t))
1149 (delete-char 1)))))
1150
1151(defun term--filter-buffer-substring (content)
1152 (with-temp-buffer
1153 (insert content)
1154 (term--remove-fake-newlines)
1155 (buffer-string)))
1156
1157(defun term--unwrap-visible-long-lines (width)
1158 ;; Unwrap lines longer than width using fake newlines. Only do it
1159 ;; for lines that are currently visible (i.e. following the home
1160 ;; marker). Invisible lines don't have to be unwrapped since they
1161 ;; are unreachable using the cursor movement anyway. Not having to
1162 ;; unwrap the entire buffer means the runtime of this function is
1163 ;; bounded by the size of the screen instead of the buffer size.
1164
1165 (save-excursion
1166 ;; We will just assume that our accounting for the home marker is
1167 ;; correct, i.e. programs will not try to reach any position
1168 ;; earlier than this marker.
1169 (goto-char term-home-marker)
1170
1171 (move-to-column width)
1172 (while (not (eobp))
1173 (if (eolp)
1174 (forward-char)
1175 (let ((inhibit-read-only t))
1176 (term-unwrap-line)))
1177 (move-to-column width))))
1178
1135(defun term-reset-size (height width) 1179(defun term-reset-size (height width)
1136 (when (or (/= height term-height) 1180 (when (or (/= height term-height)
1137 (/= width term-width)) 1181 (/= width term-width))
1182 ;; Delete all newlines used for wrapping
1183 (when (/= width term-width)
1184 (save-excursion
1185 (term--remove-fake-newlines)))
1138 (let ((point (point))) 1186 (let ((point (point)))
1139 (setq term-height height) 1187 (setq term-height height)
1140 (setq term-width width) 1188 (setq term-width width)
@@ -1147,7 +1195,8 @@ Entry to this mode runs the hooks on `term-mode-hook'."
1147 (setq term-start-line-column nil) 1195 (setq term-start-line-column nil)
1148 (setq term-current-row nil) 1196 (setq term-current-row nil)
1149 (setq term-current-column nil) 1197 (setq term-current-column nil)
1150 (goto-char point)))) 1198 (goto-char point))
1199 (term--unwrap-visible-long-lines width)))
1151 1200
1152;; Recursive routine used to check if any string in term-kill-echo-list 1201;; Recursive routine used to check if any string in term-kill-echo-list
1153;; matches part of the buffer before point. 1202;; matches part of the buffer before point.
@@ -3719,7 +3768,10 @@ all pending output has been dealt with."))
3719;; if the line above point wraps around, add a ?\n to undo the wrapping. 3768;; if the line above point wraps around, add a ?\n to undo the wrapping.
3720;; FIXME: Probably should be called more than it is. 3769;; FIXME: Probably should be called more than it is.
3721(defun term-unwrap-line () 3770(defun term-unwrap-line ()
3722 (when (not (bolp)) (insert-before-markers ?\n))) 3771 (when (not (bolp))
3772 (let ((old-point (point)))
3773 (insert-before-markers ?\n)
3774 (put-text-property old-point (point) 'term-line-wrap t))))
3723 3775
3724(defun term-erase-in-line (kind) 3776(defun term-erase-in-line (kind)
3725 (when (= kind 1) ;; erase left of point 3777 (when (= kind 1) ;; erase left of point