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: Re: Feedback on getting rid of `term-suppress-hard-newline' Date: Wed, 16 Jan 2019 09:14:19 -0500 Message-ID: <87sgxsr8p0.fsf@gmail.com> References: <87efanc576.fsf@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1547647968 29387 195.159.176.226 (16 Jan 2019 14:12:48 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 16 Jan 2019 14:12:48 +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 Jan 16 15:12:43 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gjlvu-0007Uj-9X for ged-emacs-devel@m.gmane.org; Wed, 16 Jan 2019 15:12:42 +0100 Original-Received: from localhost ([127.0.0.1]:33858 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjly1-00082T-37 for ged-emacs-devel@m.gmane.org; Wed, 16 Jan 2019 09:14:53 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:44565) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjlxp-00081S-Ia for emacs-devel@gnu.org; Wed, 16 Jan 2019 09:14:42 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjlxk-0000Mj-Gv for emacs-devel@gnu.org; Wed, 16 Jan 2019 09:14:41 -0500 Original-Received: from mail-qk1-x72a.google.com ([2607:f8b0:4864:20::72a]:46101) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjlxi-0008Vq-Dk for emacs-devel@gnu.org; Wed, 16 Jan 2019 09:14:34 -0500 Original-Received: by mail-qk1-x72a.google.com with SMTP id q1so3765850qkf.13 for ; Wed, 16 Jan 2019 06:14:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=references:user-agent:from:to:subject:in-reply-to:date:message-id :mime-version; bh=l8NgV1JpB3SgcgOmtbqbDyZWtOthiuhquTvvh3hVoMU=; b=HXAfghs+prasdH+KngmhALW1mNvnPeDckAK8NgnNlwnuWsEA40in1M8Ocl/VOpxYpS Ftto51CXlkGtXdBsb4VdtZd6YYZf6mOGZ3i8LiB9wnL8G+E0P3IWfos0HIxPCC1orY+4 6W03kJmSJUr3M8nXQgY79o0m4mv17/GUQXkxv04Q5o8Wbi1iGUN+xELNXLZ410ouUUBU A1h2MTRIFdDrmm4LJbeFR+QGx/RJkhydNxSA0TQ8cGnP0GUdC5Fq5xRALt9dQQamo9Bn sgBXZZRDyk+1ZayzIQtZz1dwOm8FaOUTZGD6ZZ5aGtcLN6pXA8vv03qegQ/LsPWJnunO c7tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:references:user-agent:from:to:subject :in-reply-to:date:message-id:mime-version; bh=l8NgV1JpB3SgcgOmtbqbDyZWtOthiuhquTvvh3hVoMU=; b=Y9QsxVEazII8tziFhc5epLcurE+n+YZbm034UHEOB9ucng/i85NWmwnhFnEFu8W+ER ctT0kUBjiHcgxhUPTDfUJLndqhWFWi/LS2ndHPVgHkLexrASogaZSdUBgtaadHCBMXhq E2lULQeXMBBk+sTolfYq03mEYTSlnJuWfdG+V2QIQOZIXckFiMlTpeJdcgI9k6ATRCYP /5SLFkhIUA23t4cWWyLwLTrIX8ygIj6ff+s5E8mTzgdg46Hi02nNeSIVHg3iIK6QupAw Fir5dupRoIH5WnsbWeh07VFW1B7/czT0wfEh4K/MmhX7fwaAv3reSCIGvJDe/1wkNBmf rGDA== X-Gm-Message-State: AJcUukfE4xzy/V6ipuP7dkwtEJzOgGfCSSyJeJQelm8H97hK/a9Y/eU8 0UqpV1lqQn2N7UaXryvsCYuVQGXqRvI= X-Google-Smtp-Source: ALg8bN6cYyYNwrPqax+55vgZC0hxue/XR34uyIc4gvs+QewvCxvnw2U2lDtUL7pcmkGGTj4myBv1PA== X-Received: by 2002:a37:b785:: with SMTP id h127mr6630139qkf.294.1547648062934; Wed, 16 Jan 2019 06:14:22 -0800 (PST) Original-Received: from amun ([142.154.219.2]) by smtp.gmail.com with ESMTPSA id a70sm43358316qkc.81.2019.01.16.06.14.20 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 16 Jan 2019 06:14:21 -0800 (PST) In-reply-to: <87efanc576.fsf@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::72a 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:232395 Archived-At: ping John Shahid writes: > 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. > > 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