Received: (at submit) by debbugs.gnu.org; 11 Apr 2025 07:00:29 +0000 From debbugs-submit-bounces <at> debbugs.gnu.org Fri Apr 11 03:00:29 2025 Received: from localhost ([127.0.0.1]:48364 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>) id 1u38NI-0003KR-3Z for submit <at> debbugs.gnu.org; Fri, 11 Apr 2025 03:00:29 -0400 Received: from lists.gnu.org ([2001:470:142::17]:36150) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from <szermatt@HIDDEN>) id 1u2vsT-0002FF-7k for submit <at> debbugs.gnu.org; Thu, 10 Apr 2025 13:39:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <szermatt@HIDDEN>) id 1u2vsF-00058P-M2 for bug-gnu-emacs@HIDDEN; Thu, 10 Apr 2025 13:39:36 -0400 Received: from mail-wm1-x32f.google.com ([2a00:1450:4864:20::32f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <szermatt@HIDDEN>) id 1u2vsC-0006Sl-Lg for bug-gnu-emacs@HIDDEN; Thu, 10 Apr 2025 13:39:35 -0400 Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-43cf05f0c3eso8534015e9.0 for <bug-gnu-emacs@HIDDEN>; Thu, 10 Apr 2025 10:39:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1744306769; x=1744911569; darn=gnu.org; h=mime-version:message-id:date:subject:to:from:from:to:cc:subject :date:message-id:reply-to; bh=Uy280Kv619JyNomjZb0AMww8NXByGprG+ZdPUvKXCx4=; b=YEyIInlbAN5Um6+KhI+Wf9VLTP2gD0c+K7gbF+d03Cxvpw9dA29XvFCDppM+8xbkE0 PQW2sbkjGiMfix+yoEHOpTBMQ2g5UdJ69sTBdNs0JEjonKrz23orl2sTQ8eb4NEDWLD1 wBy8LJ8TnJH2Alifi9zHxui9CkdxkUxwoauzpHZJP53UoGAAyng+PT89tDRoSAzoFmSs gLhCxw8sl+Yoice9tsSyPGKzXTU5+aXjnFMPOar2pKs8GqXOz6zROW57REsdrYt6YZ2w TyMuFi+ICYwhV4jv40QceddMxJvHLn9FR0RBjJOCfRle01fBb8Lf7mlUOLDixemkQjZK 9Mxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744306769; x=1744911569; h=mime-version:message-id:date:subject:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=Uy280Kv619JyNomjZb0AMww8NXByGprG+ZdPUvKXCx4=; b=ORmAulKKaxpdEZK8lgN8APvemHz6HloeL+uXz0AZ/kWH9IEsws+Sv6sLbFof2VbXMp 8HUQoMsxCk44Ke76DGSVvMRf8syaZfikitYU9ZJ/3As3+YgXhaCRTbSObGd9qEIZZ6PT I+AJX3ZojQKu8lyN7FtXD/iNdAcWmYV5CgW67Wmay9nUEAU8Gbl8yvWhTfTgWrsNB8Fr /mBXNG7FFTsLjEB9+MFl08gwVSY9qDFdYnDUpiv7+jWOnTMflcVA4/tCS7/RJ55JLblJ /joyNZ0M3CHvBPHNJJ2PrnYCvfGPG4ADox/EuV7unvRrlW+67cLPqGwVSLzfxJ/jwF7S 2t2A== X-Gm-Message-State: AOJu0YwL1FfyJ/0kUetUzhIOLGQoZactF92xSaB1TMvXQd4tOrRGkBVZ W3qc0+2JieopzUCrZIeHyRQ6sWc/U6Ku9rrRS49Qait5gRD//Ky57diNOSwyT0VmtQ== X-Gm-Gg: ASbGncuv9oTquuFBT/TZcreTrfgVIFuBCS1t3bkzJkjWWtl7Q+9xuY5EgELC+RzZyAF GG0ukCMVouRL47jc2acV5RJXl6HSoTEeQc10GewmfSQ7FGc+0jNssPLm60RovGCZczbfmRQG2Pr B7Tiz1EMVXyPpF2gCyR1QK5JagJS6tOyorjP3NhgCiWaE2Hkvfcui4pcqFB1LrvBTXua30S4nSm Q4T9nUIzIfLE7B/1WIPUE82A+eSBNNVt3G8klrCUJDZmB949c2v7V7i0jO0KN37e99+/qLwgFCw 8ML2Tm3IFWAKaBONzvIBGGfra3B3Pd+p69050YdW43ip+QyMaICGEc4j9jXUhaGQoupXHg== X-Google-Smtp-Source: AGHT+IFVnqDXtx1gJ0Q4mUxM1n+KNk1iWymJfCVJ8HZ6rCH6GJrRLblIhzf5aWL9T/c5Z++qGozm+w== X-Received: by 2002:a05:600c:1550:b0:43d:1c3:cb2e with SMTP id 5b1f17b1804b1-43f2ff0497cmr32104135e9.17.1744306768878; Thu, 10 Apr 2025 10:39:28 -0700 (PDT) Received: from boomer.zia ([62.74.10.127]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39d89378daasm5470375f8f.38.2025.04.10.10.39.27 for <bug-gnu-emacs@HIDDEN> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Apr 2025 10:39:28 -0700 (PDT) From: Stephane Zermatten <szermatt@HIDDEN> To: bug-gnu-emacs@HIDDEN Subject: [PATCH] Test and fix term-buffer-vertical-motion Date: Thu, 10 Apr 2025 20:39:26 +0300 Message-ID: <m2cydjq5kh.fsf@HIDDEN> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=2a00:1450:4864:20::32f; envelope-from=szermatt@HIDDEN; helo=mail-wm1-x32f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.0 (+) X-Debbugs-Envelope-To: submit X-Mailman-Approved-At: Fri, 11 Apr 2025 03:00:25 -0400 X-BeenThere: debbugs-submit <at> debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: <debbugs-submit.debbugs.gnu.org> List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe> List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/> List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org> List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help> List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe> Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org> X-Spam-Score: -0.0 (/) --=-=-= Content-Type: text/plain Tags: patch In my code, I'm using hidden terminal buffers created by term.el, then periodically copy their content to another buffer. The term-mode buffer is not normally shown on any window. https://github.com/szermatt/mistty This doesn't work very well with the default term-buffer-vertical-motion implementation. I get very strange behavior from term in such a case that disappear if the term buffer is shown on any window. To reproduce one issue: - Open term.el, go to term-emulate-terminal and replace: (setf term-vertical-motion (if (eq (window-buffer) (current-buffer)) 'vertical-motion 'term-buffer-vertical-motion)) with: (setf term-vertical-motion 'term-buffer-vertical-motion) (It is cheating a bit but much easier than trying to control a term buffer that's not tied to a window.) - Start zsh with M-x term (because it supports right prompts) - Type RPS1='< right' - Now type any command, such as "echo ok" and press enter. The command disappear with no output. The output never leaves the current line. - Type RPS1='' to go back to normal That's with term-suppress-hard-newline left to nil, the default value. The problem, I've found, is that term-buffer-vertical-motion has issues with some corner cases, one of which is line whose width correspond exactly to the line width. It's especially annoying given that vertical-motion with term-suppress-hard-newline nil could very well just be replaced by forward-line, and I'm doing just that as a workaround: (cl-letf (((symbol-function 'term-buffer-vertical-motion) (lambda (count) (let ((start-point (point)) (res (forward-line count))) (setq res (- count res)) (when (and (> count 0) (= (point) (point-max)) (> (point) start-point) (not (eq ?\n (char-before (point-max))))) (cl-decf res)) res)))) In this patch, however, to be nicer in the case where term-suppress-hard-newline is non-nil, I propose to test term-buffer-vertical-motion and fix the issues. term-buffer-vertical-motion should always behave like vertical-motion (assuming no display shenanigans or characters with different width), so I used that for comparison. In GNU Emacs 30.1 (build 2, x86_64-apple-darwin23.6.0, NS appkit-2487.70 Version 14.7.4 (Build 23H420)) of 2025-03-24 built on boomer.zia Windowing system distributor 'Apple', version 10.3.2487 System Description: macOS 14.7.4 Configured using: 'configure --disable-dependency-tracking --disable-silent-rules --enable-locallisppath=/usr/local/share/emacs/site-lisp --infodir=/usr/local/Cellar/emacs-plus@30/30.1/share/info/emacs --prefix=/usr/local/Cellar/emacs-plus@30/30.1 --with-native-compilation=aot --with-xml2 --with-gnutls --without-compress-install --without-dbus --without-imagemagick --with-modules --with-rsvg --with-webp --with-ns --disable-ns-self-contained 'CFLAGS=-O2 -DFD_SETSIZE=10000 -DDARWIN_UNLIMITED_SELECT -I/usr/local/opt/sqlite/include -I/usr/local/opt/gcc/include -I/usr/local/opt/libgccjit/include' 'LDFLAGS=-L/usr/local/opt/sqlite/lib -L/usr/local/lib/gcc/14 -I/usr/local/opt/gcc/include -I/usr/local/opt/libgccjit/include'' --=-=-= Content-Type: text/patch Content-Disposition: attachment; filename=0001-Test-and-fix-term-buffer-vertical-motion.patch From 807237230038126f52ae1ac5b5f5023c80d660df Mon Sep 17 00:00:00 2001 From: Stephane Zermatten <szermatt@HIDDEN> Date: Wed, 2 Apr 2025 18:44:59 +0300 Subject: [PATCH] Test and fix term-buffer-vertical-motion term-buffer-vertical-motion simulates vertical-motion when no window is available. This change makes sure that the simulation is correct when point is at the beginning or end of lines. The fix is relevant even when term-suppress-hard-newline is nil. * lisp/term.el --- lisp/term.el | 81 ++++++----- test/lisp/term-tests.el | 303 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 348 insertions(+), 36 deletions(-) diff --git a/lisp/term.el b/lisp/term.el index 862103d88e6..1defafc3ad1 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -2858,42 +2858,51 @@ term-vertical-motion (defun term-buffer-vertical-motion (count) (cond ((= count 0) - (move-to-column (* term-width (/ (current-column) term-width))) - 0) - ((> count 0) - (let ((H) - (todo (+ count (/ (current-column) term-width)))) - (end-of-line) - ;; The loop iterates over buffer lines; - ;; H is the number of screen lines in the current line, i.e. - ;; the ceiling of dividing the buffer line width by term-width. - (while (and (<= (setq H (max (/ (+ (current-column) term-width -1) - term-width) - 1)) - todo) - (not (eobp))) - (setq todo (- todo H)) - (forward-char) ;; Move past the ?\n - (end-of-line)) ;; and on to the end of the next line. - (if (and (>= todo H) (> todo 0)) - (+ (- count todo) H -1) ;; Hit end of buffer. - (move-to-column (* todo term-width)) - count))) - (t ;; (< count 0) ;; Similar algorithm, but for upward motion. - (let ((H) - (todo (- count))) - (while (and (<= (setq H (max (/ (+ (current-column) term-width -1) - term-width) - 1)) - todo) - (progn (beginning-of-line) - (not (bobp)))) - (setq todo (- todo H)) - (backward-char)) ;; Move to end of previous line. - (if (and (>= todo H) (> todo 0)) - (+ count todo (- 1 H)) ;; Hit beginning of buffer. - (move-to-column (* (- H todo 1) term-width)) - count))))) + (let ((col (current-column))) + (when (and (eq ?\n (char-after (point))) (> col 0)) + (decf col)) + (move-to-column (* term-width (/ col term-width)))) + 0) + ((> count 0) + (let ((H) + (todo (if (eolp) + count + (+ count (/ (current-column) term-width))))) + (end-of-line) + ;; The loop iterates over buffer lines; + ;; H is the number of screen lines in the current line, i.e. + ;; the ceiling of dividing the buffer line width by term-width. + (while (and (<= (setq H (max (/ (+ (current-column) term-width -1) + term-width) + 1)) + todo) + (not (eobp))) + (setq todo (- todo H)) + (forward-char) ;; Move past the ?\n + (end-of-line)) ;; and on to the end of the next line. + (if (and (>= todo H) (> todo 0)) + (+ (- count todo) H -1) ;; Hit end of buffer. + (move-to-column (* todo term-width)) + count))) + (t ;; (< count 0) ;; Similar algorithm, but for upward motion. + (let ((H) + (todo (- count))) + (while (and (<= (setq H (max (/ (+ (current-column) + term-width + (if (eolp) -1 0)) + term-width) + 1)) + todo) + (progn + (beginning-of-line) + + (not (bobp)))) + (setq todo (- todo H)) + (backward-char)) ;; Move to end of previous line. + (if (and (>= todo H) (> todo 0)) + (+ count todo (- 1 H)) ;; Hit beginning of buffer. + (move-to-column (* (- H todo 1) term-width)) + count))))) ;; The term-start-line-column variable is used as a cache. (defun term-start-line-column () diff --git a/test/lisp/term-tests.el b/test/lisp/term-tests.el index 5ef8c1174df..bc40b3acab0 100644 --- a/test/lisp/term-tests.el +++ b/test/lisp/term-tests.el @@ -102,6 +102,46 @@ term-test-screen-from-input (if return-var (buffer-local-value return-var (current-buffer)) (buffer-substring (point-min) (point-max)))))) +(defun term-test-vertical-motion (count text start-point) + "Run `term-buffer-vertical-motion' COUNT and return the result. + +This function sets up a buffer with TEXT as content, move the point to +START-POINT, then call `term-buffer-vertical-motion' and return a CONS +containing its return value and the final point. + +`term-width' must be set for`term-buffer-vertical-motion' to work. + +Additionally, if `term-width' correspond to `window-max-chars-per-line', +which under batch test is 79, this function compares the result with +`vertical-motion' and reports any inconsistencies as a special return +value meant to fail the tests. This is basically a 3-way test. + +The result from `vertical-motion' is always the correct one, since +`term-buffer-vertical-motion' simulates it." + (ert-with-test-buffer () + (insert text) + (let ((actual (save-excursion + (goto-char start-point) + (cons (term-buffer-vertical-motion count) + (point))))) + (if (= (window-max-chars-per-line) term-width) + ;; Since term-width allows it, compare with vertical-motion, + ;; which term-buffer-vertical-motion simulates. If the two + ;; report inconsistent result, the returned value cause the + ;; test to fail. + (let ((goal (if (equal (window-max-chars-per-line) + term-width) + (save-excursion + (goto-char start-point) + (cons (vertical-motion count) + (point)))))) + (if (equal actual goal) + actual + `(inconsistent-result actual ,actual goal ,goal))) + + ;; The result from term-buffer-vertical-motion + actual)))) + (ert-deftest term-simple-lines () (skip-when (memq system-type '(windows-nt ms-dos))) (let ((str "\ @@ -418,6 +458,269 @@ term-undecodable-input (term-test-screen-from-input 40 1 bytes))))) +(ert-deftest term-buffer-vertical-motion-0-unwrapped-line () + (let* ((term-width 79) ; usual win body width in batch mode + (line (concat (make-string term-width ?1) "\n"))) + ;; vertical-motion 0 goes to the beginning of the line + (should + (equal '(0 . 1) + ;; from the beginning of the line + (term-test-vertical-motion 0 line 1))) + (should + (equal '(0 . 1) + ;; from the middle of the line + (term-test-vertical-motion 0 line 5))) + (should + (equal '(0 . 1) + ;; from the \n + (term-test-vertical-motion 0 line 80))))) + +(ert-deftest term-buffer-vertical-motion-0-wrapped-line () + (let* ((term-width 79) ; usual win body width in batch mode + (line (concat (make-string term-width ?1) + (make-string term-width ?2) + (make-string term-width ?3) + "\n")) + (line-1-bol 1) + (line-2-bol (+ line-1-bol term-width)) + (line-3-bol (+ line-2-bol term-width)) + (final-newline (+ line-3-bol term-width))) + ;; vertical-motion 0 goes to the beginning of the line, taking + ;; wrapping into account. + + ;; vertical-motion 0 from line 1 + (should + (equal (cons 0 line-1-bol) + (term-test-vertical-motion 0 line line-1-bol))) + (should + (equal (cons 0 line-1-bol) + (term-test-vertical-motion 0 line (+ line-1-bol 5)))) + (should + (equal (cons 0 line-1-bol) + (term-test-vertical-motion 0 line (+ line-1-bol 9)))) + + ;; vertical-motion 0 from line 2 + (should + (equal (cons 0 line-2-bol) + (term-test-vertical-motion 0 line line-2-bol))) + (should + (equal (cons 0 line-2-bol) + (term-test-vertical-motion 0 line (+ line-2-bol 5)))) + (should + (equal (cons 0 line-2-bol) + (term-test-vertical-motion 0 line (+ line-2-bol 9)))) + + ;; vertical-motion 0 from line 3 + (should + (equal (cons 0 line-3-bol) + (term-test-vertical-motion 0 line line-3-bol))) + (should + (equal (cons 0 line-3-bol) + (term-test-vertical-motion 0 line (+ line-3-bol 5)))) + (should + (equal (cons 0 line-3-bol) + (term-test-vertical-motion 0 line (+ line-3-bol 9)))) + (should + (equal (cons 0 line-3-bol) + (term-test-vertical-motion 0 line final-newline))))) + +(ert-deftest term-buffer-vertical-motion-down-unwrapped-lines () + (let* ((term-width 79) ; usual win body width in batch mode + (text (concat (make-string 79 ?1) "\n" + (make-string 79 ?2) "\n")) + (line-1-bol 1) + (line-1-middle 5) + (line-1-newline (+ line-1-bol term-width)) + (line-2-bol (+ line-1-bol term-width 1)) + (line-3-bol (+ line-2-bol term-width 1))) + ;; vertical-motion count, with count >0, goes down count lines to + ;; the beginning of that line. + + ;; vertical-motion 1 from line 1 + (should + (equal (cons 1 line-2-bol) + (term-test-vertical-motion 1 text line-1-bol))) + (should + (equal (cons 1 line-2-bol) + (term-test-vertical-motion 1 text line-1-middle))) + (should + (equal (cons 1 line-2-bol) + (term-test-vertical-motion 1 text line-1-newline))) + + ;; vertical-motion 2 from line 1 + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 2 text line-1-bol))) + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 2 text line-1-middle))) + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 2 text line-1-newline))) + + ;; vertical motion 3 from line 1 + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 3 text line-1-bol))) + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 3 text line-1-middle))) + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 3 text line-1-newline))))) + +(ert-deftest term-buffer-vertical-motion-down-wrapped-lines () + (let* ((term-width 79) ; usual win body width in batch mode + (text (concat (make-string term-width ?1) + (make-string term-width ?2) + "\n" + (make-string term-width ?3) + "\n")) + (line-1-bol 1) + (line-1-middle 5) + (line-1-eol (+ line-1-bol term-width -1)) + (line-2-bol (+ line-1-bol term-width)) + (line-3-bol (+ line-2-bol term-width 1)) + (final-newline (1+ (length text)))) + ;; vertical-motion count, with count >0, goes down count lines to + ;; the beginning of that line, taking wrapping into account. + + ;; vertical-motion 1 from line 1 + (should + (equal (cons 1 line-2-bol) + (term-test-vertical-motion 1 text line-1-bol))) + (should + (equal (cons 1 line-2-bol) + (term-test-vertical-motion 1 text line-1-middle))) + (should + (equal (cons 1 line-2-bol) + (term-test-vertical-motion 1 text line-1-eol))) + + ;; vertical-motion 2 from line 1 + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 2 text line-1-bol))) + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 2 text line-1-middle))) + (should + (equal (cons 2 line-3-bol) + (term-test-vertical-motion 2 text line-1-eol))) + + ;; vertical-motion 3 from line 1 + (should + (equal (cons 3 final-newline) + (term-test-vertical-motion 3 text line-1-bol))) + (should + (equal (cons 3 final-newline) + (term-test-vertical-motion 3 text line-1-middle))) + (should + (equal (cons 3 final-newline) + (term-test-vertical-motion 3 text line-1-eol))) + + ;; vertical-motion 4 from line 1 + (should + (equal (cons 3 final-newline) + (term-test-vertical-motion 4 text line-1-bol))) + (should + (equal (cons 3 final-newline) + (term-test-vertical-motion 4 text line-1-middle))) + (should + (equal (cons 3 final-newline) + (term-test-vertical-motion 4 text line-1-eol))))) + +(ert-deftest term-buffer-vertical-motion-up-unwrapped-lines () + (let* ((term-width 79) ; usual win body width in batch mode + (text (concat (make-string 79 ?1) "\n" + (make-string 79 ?2) "\n" + (make-string 79 ?3) "\n")) + (line-1-bol 1) + (line-2-bol (+ line-1-bol term-width 1)) + (line-3-bol (+ line-2-bol term-width 1)) + (line-3-middle (+ line-3-bol 5)) + (line-3-newline (+ line-3-bol term-width 1))) + ;; vertical-motion count, with count <0, goes up count lines to + ;; the beginning of that line. + + ;; vertical-motion -1 from line 3 + (should + (equal (cons -1 line-2-bol) + (term-test-vertical-motion -1 text line-3-bol))) + (should + (equal (cons -1 line-2-bol) + (term-test-vertical-motion -1 text line-3-middle))) + (should + (equal (cons -1 line-3-bol) + (term-test-vertical-motion -1 text line-3-newline))) + + ;; vertical-motion -2 from line 3 + (should + (equal (cons -2 line-1-bol) + (term-test-vertical-motion -2 text line-3-bol))) + (should + (equal (cons -2 line-1-bol) + (term-test-vertical-motion -2 text line-3-middle))) + (should + (equal (cons -2 line-2-bol) + (term-test-vertical-motion -2 text line-3-newline))) + + ;; vertical-motion -2 from line 3 goes to point-min + (should + (equal '(-2 . 1) + (term-test-vertical-motion -3 text line-3-bol))) + (should + (equal '(-2 . 1) + (term-test-vertical-motion -3 text line-3-middle))) + (should + (equal '(-3 . 1) + (term-test-vertical-motion -3 text line-3-newline))))) + +(ert-deftest term-buffer-vertical-motion-up-wrapped-lines () + (let* ((term-width 79) ; usual win body width in batch mode + (text (concat (make-string 79 ?1) + (make-string 79 ?2) + (make-string 79 ?3) "\n")) + (line-1-bol 1) + (line-2-bol (+ line-1-bol term-width)) + (line-3-bol (+ line-2-bol term-width)) + (line-3-middle (+ line-3-bol 5)) + (line-3-newline (+ line-3-bol term-width 1))) + ;; vertical-motion count, with count <0, goes up count lines to + ;; the beginning of that line, taking wrapping into account. + + ;; vertical-motion -1 from line 3 + (should + (equal (cons -1 line-3-bol) + (term-test-vertical-motion -1 text line-3-newline))) + (should + (equal (cons -1 line-2-bol) + (term-test-vertical-motion -1 text line-3-middle))) + (should + (equal (cons -1 line-2-bol) + (term-test-vertical-motion -1 text line-3-bol))) + + ;; vertical-motion -2 from line 3 + (should + (equal (cons -2 line-2-bol) + (term-test-vertical-motion -2 text line-3-newline))) + (should + (equal (cons -2 line-1-bol) + (term-test-vertical-motion -2 text line-3-middle))) + (should + (equal (cons -2 line-1-bol) + (term-test-vertical-motion -2 text line-3-bol))) + + ;; vertical-motion -2 from line 3 goes to point-min + (should + (equal '(-3 . 1) + (term-test-vertical-motion -3 text line-3-newline))) + (should + (equal '(-2 . 1) + (term-test-vertical-motion -3 text line-3-middle))) + (should + (equal '(-2 . 1) + (term-test-vertical-motion -3 text line-3-bol))))) + (provide 'term-tests) ;;; term-tests.el ends here -- 2.47.0 --=-=-=--
Stephane Zermatten <szermatt@HIDDEN>
:bug-gnu-emacs@HIDDEN
.
Full text available.bug-gnu-emacs@HIDDEN
:bug#77722
; Package emacs
.
Full text available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997 nCipher Corporation Ltd,
1994-97 Ian Jackson.