From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: John Shahid Newsgroups: gmane.emacs.devel Subject: Feedback on getting rid of `term-suppress-hard-newline' Date: Wed, 12 Dec 2018 07:14:37 -0500 Message-ID: <87efanc576.fsf@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1544616769 28739 195.159.176.226 (12 Dec 2018 12:12:49 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 12 Dec 2018 12:12:49 +0000 (UTC) User-Agent: mu4e 1.1.0; emacs 27.0.50 To: emacs-devel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Dec 12 13:12:45 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gX3Nc-0007NW-R4 for ged-emacs-devel@m.gmane.org; Wed, 12 Dec 2018 13:12:45 +0100 Original-Received: from localhost ([::1]:44100 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gX3Pj-0005oX-HA for ged-emacs-devel@m.gmane.org; Wed, 12 Dec 2018 07:14:55 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:50877) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gX3Pc-0005mR-Dg for emacs-devel@gnu.org; Wed, 12 Dec 2018 07:14:49 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gX3PX-0004Ey-Gi for emacs-devel@gnu.org; Wed, 12 Dec 2018 07:14:48 -0500 Original-Received: from mail-qk1-x736.google.com ([2607:f8b0:4864:20::736]:34824) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gX3PX-0004Ea-9z for emacs-devel@gnu.org; Wed, 12 Dec 2018 07:14:43 -0500 Original-Received: by mail-qk1-x736.google.com with SMTP id w204so10583767qka.2 for ; Wed, 12 Dec 2018 04:14:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=user-agent:from:to:subject:date:message-id:mime-version; bh=r5iJFjWWXpoLJ0y8BRITsGhZySdMHwUXt/UvJw9CmpA=; b=W5JGTG2NC1FeX5JstiZrNVD5F6nxDWQgB33tBTp79EhFGnb/j6MzgE2BfbtgpQUBN0 VuU8ZIM5ZKwdsH1wdVQWnIoe806g02Fx92y3NsyOBb8P/MpvwFaOWuIcn8YrnE7cZH4G ot8RwfrQu6mO6K5h6+fKVwOtJILOf3gQn1Su5iQzOQez4uzI9P4rp0BCsfPcwYnkFGWU SBjdMGj/5w1V4MpVn9AnNmmnru1zIQaH9yDa5LPnS6DPPp+gXDM10XH3lHAXYXL0ohvD hqltDV0a5x8WmMxQhgMEjPLWkipnW62b4iVueyS0XHG8nnwe6RLgPy5xIThgPP+rKJdA lZ2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:user-agent:from:to:subject:date:message-id :mime-version; bh=r5iJFjWWXpoLJ0y8BRITsGhZySdMHwUXt/UvJw9CmpA=; b=a3SdNDgaB9PyR4SBJzg13xgVOKAnV4NQ8Y4X1L45sE1cvcm3Xpn8QuoJ6xjzPDbh4L wBLH9c9pP4RnhrhIoWUTFSkD79GeNYZUB35EWRLRa00ihtotVWFEFQJsbB+wkUbUahoW p4V1NKmcnRKGnQe1GrH9YFjb1HQzkGt8X4OJvigw++9TB46TgqCfJHcfjEwSNjpAIJBt MhWIpSkl0ikH0QFZiYJawmuCkm6AEtzGhrZXPggRqSHKDdTsKeU3U9Q1I6cBJdCd9MBd jvm5wU5uCeMWanijA2lIVVxJghYPhqsfPypOsO6gq7ndXROOrUiIruvU2HC6agaP35fI LieA== X-Gm-Message-State: AA+aEWaX0hDJKSjXstZJ6fa0C8/nC6A9NtnGgixEMVk/AlSbwcHle0oX Z0JmIVt5pcfpKvz3biaKSppCVk2j X-Google-Smtp-Source: AFSGD/X6t1lRpk3NClOJISvmbn9cXzX8W0Jy8i6jB7n/Nif23uf0P6ShekH1rsUhdcDIutT3ViHXAg== X-Received: by 2002:a37:8d01:: with SMTP id p1mr7878075qkd.91.1544616881941; Wed, 12 Dec 2018 04:14:41 -0800 (PST) Original-Received: from amun (cpe-104-162-86-217.nyc.res.rr.com. [104.162.86.217]) by smtp.gmail.com with ESMTPSA id x24sm13638658qtk.70.2018.12.12.04.14.40 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 12 Dec 2018 04:14:40 -0800 (PST) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::736 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:231774 Archived-At: --=-=-= Content-Type: text/plain Hi all, I should add a little bit of context and explain why I am trying to get rid of `term-suppress-hard-newline'. I use ansi-term on a daily basis and I stay in "char mode" all the time unless I'm copying something from the terminal output. ansi-term adds extra newlines at the to break long lines into multiple lines of text that fit the terminal width. There is an option to disable this behavior called `term-suppress-hard-newline'. This option is useful when: 1. The window dimensions changes to accommodate the long line(s). It is nice to see the line unwrap and adjust to the larger window width. 2. The text is copied from the terminal buffer to another buffer. It is nice not to have extra newlines that weren't part of the original output, specially when copying large amounts of text from the terminal output. But, `term-suppress-hard-newline' feels like a hack. It has few edge cases that I have been running into. For example, `term-unwrap-line' can break long lines unexpectedly. This causes edits to the beginning of the command line (e.g. inserting or removing a character) to mess up the terminal screen. Furthermore `term-down' doesn't adjust the `term-current-column' and `term-start-line-column' properly. It just assumes that the line starts at column 0, which isn't the case when a long line is wrapped around. I think those issues I mentioned above are fix-able. But, I think that `term-suppress-hard-newline' breaks an assumption that is made in the rest of the code. Instead, I experimented with a different approach that i would like to get some feedback on. 1. Add a text property to mark extra newlines when they are inserted (e.g. `term-newline' is set to `t') 2. On resize reflow the text. That is, remove the extra newlines and add new ones to make sure that lines fit in the terminal width. 3. Set a `filter-buffer-substring-function' to remove those extra newlines. I attached a patch that I have been using locally. Let me know what you think. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-wip-add-some-reflow-and-copy-logic.patch Content-Description: patch demonstrating terminal text reflow >From 2b6332a66b56fea987fe70d336c1742ae6352ffa Mon Sep 17 00:00:00 2001 From: John Shahid Date: Sat, 8 Dec 2018 10:32:36 -0500 Subject: [PATCH] wip: add some reflow and copy logic TODO: need to be tested --- lisp/term.el | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/lisp/term.el b/lisp/term.el index 9f8f1f703a..024adb7f70 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -1106,6 +1106,7 @@ term-mode (make-local-variable 'term-scroll-show-maximum-output) (make-local-variable 'term-ptyp) (make-local-variable 'term-exec-hook) + (setq-local filter-buffer-substring-function 'term-filter-buffer-substring) (set (make-local-variable 'term-vertical-motion) 'vertical-motion) (set (make-local-variable 'term-pending-delete-marker) (make-marker)) (make-local-variable 'term-current-face) @@ -1132,9 +1133,33 @@ term-mode (setq term-input-ring (make-ring term-input-ring-size))) (term-update-mode-line)) +(defun term-insert-fake-newline (&optional count) + (let ((old-point (point))) + (term-insert-char ?\n count) + (put-text-property old-point (point) 'term-newline t))) + +(defun term-remove-fake-newlines () + (goto-char (point-min)) + (while (setq fake-newline (next-single-property-change (point) + 'term-newline)) + (goto-char fake-newline) + (let (buffer-read-only) + (delete-char 1)))) + +(defun term-filter-buffer-substring (beg end &optional del) + (let ((content (buffer-substring--filter beg end del))) + (with-temp-buffer + (insert content) + (term-remove-fake-newlines) + (buffer-string)))) + (defun term-reset-size (height width) (when (or (/= height term-height) (/= width term-width)) + ;; delete all fake newlines + (when (/= width term-width) + (save-excursion + (term-remove-fake-newlines))) (let ((point (point))) (setq term-height height) (setq term-width width) @@ -1147,7 +1172,21 @@ term-reset-size (setq term-start-line-column nil) (setq term-current-row nil) (setq term-current-column nil) - (goto-char point)))) + (goto-char point)) + (save-excursion + ;; add fake newlines for the lines that are currently displayed + (forward-line (- (term-current-row))) + (beginning-of-line) + (while (not (eobp)) + (let* ((bol (line-beginning-position)) + (eol (line-end-position)) + (len (- eol bol))) + (when (> len width) + (goto-char (+ bol width)) + (let (buffer-read-only) + (term-insert-fake-newline))) + (unless (eobp) + (forward-char))))))) ;; Recursive routine used to check if any string in term-kill-echo-list ;; matches part of the buffer before point. @@ -2906,6 +2945,7 @@ term-emulate-terminal (delete-region (point) (line-end-position)) (term-down 1 t) (term-move-columns (- (term-current-column))) + (put-text-property (1- (point)) (point) 'term-newline t) (setq decoded-substring (substring decoded-substring (- term-width old-column))) (setq old-column 0))) @@ -3719,7 +3759,10 @@ term-down ;; if the line above point wraps around, add a ?\n to undo the wrapping. ;; FIXME: Probably should be called more than it is. (defun term-unwrap-line () - (when (not (bolp)) (insert-before-markers ?\n))) + (when (not (bolp)) + (let ((old-point (point))) + (insert-before-markers ?\n) + (put-text-property old-point (point) 'term-newline t)))) (defun term-erase-in-line (kind) (when (= kind 1) ;; erase left of point -- 2.19.2 --=-=-=--