Subject: bug#65531: 29.1; Inconsistent behaviour when restoring from ansi-term's alternate screen

From: Hao Chi Kiang <[email-masked]>
Date: Fri, 25 Aug 2023 10:00:30 +0000

Hi,

Emacs's ansi-term supports alternate screens and these can be used by
issuing `tput smcup' and `tput rmcup'. In ansi-term, there seems to be
a bug that results in the entire terminal being scrolled one line when
the cursor is at the end of the terminal. This means that the cursor
will be at a wrong position after restoring from alternate screen, as
shown is the following example.

Steps to reproduce
------------------

1. Open Emacs by `emacs -Q' in GUI mode
2. Maximize the GUI window so that it's wide enough to show a long shell
   command in one line.
2. C-x ansi-term
3. Issue the command in one line:
echo -n 'Hello'; tput sc; tput smcup; echo -n 'World'; tput rmcup; tput rc
4. Now the current line in the terminal should be `Hello~$ '. This is
   the correct behaviour.
5. Now press Enter key repeatedly until the cursor ends up at last line
   of the screen.
6. Issue the same command as in Step 3.
7. The terminal is now shows:
Hello
     ~$
   Notice this is a different output from that of Step 3.

The output given by Step 7 is wrong, or at least none of common
terminals such as xterm, tmux and konsole do this. 

I believe the problem is that in Step 7, the entire screen is scrolled
up by a line before the new $PS1 is printed. This is because I've been
developing a tab-completion functionality for a programming language,
and in my case even without $PS1 the entire screen is still scrolled.
You can also see this scrolling by appending '; sleep 999' to the
shell command at Step 3 in order to suppress $PS1.

Best regards,
Hao Chi Kiang

System Information
------------------

In GNU Emacs 29.1 (build 2, x86_64-unknown-linux-gnu, GTK+ Version
 3.24.38, cairo version 1.16.0) of 2023-08-03 built on a-fsn-de
Windowing system distributor 'The X.Org Foundation', version 11.0.12101008
System Description: Void Linux

Configured using:
 'configure --with-x-toolkit=gtk3 --with-xwidgets --prefix=/usr
 --sysconfdir=/etc --sbindir=/usr/bin --bindir=/usr/bin
 --mandir=/usr/share/man --infodir=/usr/share/info --localstatedir=/var
 --host=x86_64-unknown-linux-gnu --build=x86_64-unknown-linux-gnu
 '--libdir=${exec_prefix}/lib64' --with-file-notification=inotify
 --with-modules --with-jpeg --with-tiff --with-gif --with-png
 --with-webp --with-xpm --with-rsvg --without-imagemagick --with-xml2
 --with-gnutls --with-sound --with-m17n-flt --with-json --with-harfbuzz
 --with-cairo --with-libgmp --with-sqlite --with-tree-sitter
 --with-native-compilation=aot 'CFLAGS=-fno-PIE -mtune=generic -O2 -pipe
 -g -ffile-prefix-map=/builddir/emacs-29.1=.' 'CPPFLAGS= '
 'LDFLAGS=-no-pie -Wl,--as-needed ''

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LCMS2 LIBOTF LIBXML2 M17N_FLT MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER
PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS
TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM XWIDGETS GTK3 ZLIB

Important settings:
  value of $LC_COLLATE: C
  value of $LANG: sv_SE.UTF-8
  value of $XMODIFIERS: @im=fcitx
  locale-coding-system: utf-8-unix

Major mode: Shell-script

Minor modes in effect:
  sh-electric-here-document-mode: t
  windmove-mode: t
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  auto-revert-mode: t
  TeX-PDF-mode: t
  server-mode: t
  global-visible-mark-mode: t
  visible-mark-mode: t
  minions-mode: t
  shackle-mode: t
  minibuffer-depth-indicate-mode: t
  icicle-mode: t
  global-corfu-mode: t
  corfu-mode: t
  pretty-control-l-mode: t
  global-whitespace-mode: t
  shell-dirtrack-mode: t
  override-global-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  size-indication-mode: t
  column-number-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/home/hckiang/.emacs.d/elpa/transient-20220717.1713/transient hides /usr/share/emacs/29.1/lisp/transient
/home/hckiang/.emacs.d/elpa/use-package-20210207.1926/use-package-delight hides /usr/share/emacs/29.1/lisp/use-package/use-package-delight
/home/hckiang/.emacs.d/elpa/use-package-20210207.1926/use-package-jump hides /usr/share/emacs/29.1/lisp/use-package/use-package-jump
/home/hckiang/.emacs.d/elpa/use-package-20210207.1926/use-package hides /usr/share/emacs/29.1/lisp/use-package/use-package
/home/hckiang/.emacs.d/elpa/use-package-20210207.1926/use-package-core hides /usr/share/emacs/29.1/lisp/use-package/use-package-core
/home/hckiang/.emacs.d/elpa/use-package-20210207.1926/use-package-bind-key hides /usr/share/emacs/29.1/lisp/use-package/use-package-bind-key
/home/hckiang/.emacs.d/elpa/use-package-20210207.1926/use-package-ensure hides /usr/share/emacs/29.1/lisp/use-package/use-package-ensure
/home/hckiang/.emacs.d/elpa/use-package-20210207.1926/use-package-diminish hides /usr/share/emacs/29.1/lisp/use-package/use-package-diminish
/home/hckiang/.emacs.d/elpa/use-package-20210207.1926/use-package-lint hides /usr/share/emacs/29.1/lisp/use-package/use-package-lint
/home/hckiang/.emacs.d/elpa/bind-key-20210210.1609/bind-key hides /usr/share/emacs/29.1/lisp/use-package/bind-key

Features:
(shadow sort mail-extr emacsbug tabify org-capture timezone lsp-ui
lsp-ui-doc xwidget lsp-ui-imenu lsp-ui-peek lsp-ui-sideline lsp-ui-util
view lsp-zig lsp-steep lsp-svelte lsp-sqls lsp-yaml lsp-xml
lsp-vimscript lsp-vhdl lsp-volar lsp-vetur lsp-html lsp-verilog lsp-vala
lsp-v lsp-typeprof lsp-ttcn3 lsp-toml lsp-terraform lsp-tex lsp-sorbet
lsp-solargraph lsp-rust lsp-rf lsp-remark lsp-r lsp-purescript lsp-pylsp
lsp-pyls lsp-pwsh lsp-php lsp-perlnavigator lsp-perl lsp-openscad
lsp-ocaml lsp-magik lsp-nix lsp-nim lsp-nginx lsp-marksman lsp-markdown
lsp-lua lsp-kotlin lsp-json lsp-javascript lsp-idris lsp-haxe lsp-groovy
lsp-hack lsp-graphql lsp-gleam lsp-go lsp-completion lsp-gdscript
lsp-fsharp lsp-fortran lsp-eslint lsp-erlang lsp-emmet lsp-elixir
lsp-elm lsp-dockerfile lsp-dhall lsp-d lsp-css lsp-csharp lsp-crystal
lsp-cmake lsp-clojure lsp-semantic-tokens lsp-clangd lsp-beancount
lsp-bash lsp-ansible lsp-angular lsp-ada lsp-actionscript lsp-mode
lsp-protocol spinner network-stream markdown-mode lv inline ht f
f-shortdoc shortdoc s ewoc yasnippet f90 cus-start grep sh-script smie
treesit executable pcmpl-unix windmove macrostep-c cmacexp macrostep
cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine
cc-vars cc-defs vc-hg vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs
log-view vc bug-reference magit-extras magit-bookmark magit-submodule
magit-obsolete magit-popup magit-blame magit-stash magit-reflog
magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote
magit-commit magit-sequence magit-notes magit-worktree magit-tag
magit-merge magit-branch magit-reset magit-files magit-refs magit-status
magit magit-repos magit-apply magit-wip magit-log magit-diff smerge-mode
diff git-commit log-edit pcvs-util add-log magit-core magit-autorevert
autorevert magit-margin magit-transient magit-process with-editor
magit-mode transient magit-git magit-section magit-utils which-func ido
make-mode goto-addr pcmpl-git em-unix em-term term ehelp em-script
em-prompt em-ls em-hist em-pred em-glob em-extpipe em-cmpl em-dirs
esh-var em-basic em-banner em-alias esh-mode eshell esh-cmd esh-ext
esh-opt esh-proc esh-io esh-arg esh-module esh-groups esh-util vc-git
diff-mode vc-dispatcher cursor-sensor xah-math-input ess-r-mode
ess-r-flymake ess-r-xref ess-trns ess-r-package ess-r-completion
ess-roxy ess-r-syntax ess-rd hideshow ess-s-lang ess-help ess-mode
ess-inf ess-tracebug reftex-parse misearch multi-isearch mule-util
dabbrev reftex-dcr reftex-auc reftex reftex-loaddefs reftex-vars
font-latex latex latex-flymake flymake-proc flymake tex-ispell tex-style
tex crm texmathp tex-mode latexenc conf-mode org-inline-pdf face-remap
oc-basic ol-eww eww url-queue mm-url ol-mhe ol-irc ol-info ol-gnus
nnselect gnus-art mm-uu mml2015 mm-view mml-smime smime gnutls dig
gnus-sum shr pixel-fill kinsoku url-file gnus-group gnus-undo gnus-start
gnus-dbus dbus gnus-cloud nnimap nnmail mail-source utf7 nnoo gnus-spec
gnus-int gnus-range message sendmail yank-media rfc822 mml mml-sec epa
epg rfc6068 epg-config mm-decode mm-bodies mm-encode mailabbrev
gmm-utils mailheader gnus-win gnus nnheader gnus-util range ol-docview
doc-view filenotify jka-compr ol-bibtex bibtex ol-bbdb ol-w3m ol-doi
org-link-doi server visible-mark dim minions uuid calc-comb calc-ext
calc calc-loaddefs rect calc-macs rmail mail-utils ol-rmail org-caldav
icalendar diary-lib diary-loaddefs url-dav ox-odt rng-loc rng-uri
rng-parse rng-match rng-dt rng-util rng-pttrn nxml-parse nxml-ns
nxml-enc xmltok nxml-util ox-latex ox-icalendar ox-html table ox-ascii
ox-publish ox ob-latex ob-shell ob-R org-agenda org-download url-http
mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr url-gw
nsm puny async org-protocol org-fragtog org-element org-persist org-id
org-refile avl-tree org ob ob-tangle ob-ref ob-lob ob-table ob-exp
org-macro org-src ob-comint org-pcomplete org-list org-footnote
org-faces org-entities ob-emacs-lisp ob-core ob-eval org-cycle org-table
ol org-fold org-fold-core org-keys oc org-loaddefs find-func cal-menu
calendar cal-loaddefs org-version org-compat org-macs ess lisp-mnt
ess-utils ess-custom shackle trace consult compat compat-29 embark
mb-depth two-column facemenu icicles icicles-mode dired+ image-file
image-converter dired-aux icicles-cmd2 imenu completion icicles-cmd1 yow
cookie1 recentf tree-widget icicles-mcmd image-dired image-dired-tags
image-dired-external image-dired-util xdg image-mode exif doremi
filesets icicles-fn flx comp comp-cstr warnings icicles-var icicles-opt
ffap cus-theme cus-edit cus-load wid-edit bookmark+ bookmark+-key
derived dired-x crosshairs col-highlight vline hl-line+ advice hl-line
bookmark+-1 bookmark+-bmu bookmark+-lit bookmark icicles-face hexrgb
icicles-mac orderless lacarte kind-icon svg-lib svg dom xml cape corfu
gambit cmuscheme scheme edmacro kmacro cl-extra dired-sidebar
dired-subtree dired-hacks-utils dash pcase modus-vivendi-theme color
dired-single slime compile text-property-search etags fileloop generator
xref project arc-mode archive-mode noutline outline icons pp hyperspec
thingatpt disp-table pp-c-l whitespace marginalia all-the-icons-dired
dired dired-loaddefs all-the-icons all-the-icons-faces data-material
data-weathericons data-octicons data-fileicons data-faicons
data-alltheicons cl tramp tramp-loaddefs trampver tramp-integration
files-x tramp-compat rx shell pcomplete comint ansi-osc ansi-color ring
parse-time iso8601 time-date format-spec quail help-mode
modus-operandi-theme modus-themes display-line-numbers noweb-mode
finder-inf use-package use-package-ensure use-package-delight
use-package-diminish use-package-bind-key bind-key easy-mmode
use-package-core tex-site slime-autoloads url-auth info package
browse-url url url-proxy url-privacy url-expand url-methods url-history
url-cookie generate-lisp-file url-domsuf url-util mailcap url-handlers
url-parse auth-source cl-seq eieio eieio-core cl-macs password-cache
json subr-x map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs
cl-lib rmc iso-transl tooltip cconv eldoc paren electric uniquify
ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads xwidget-internal dbusbind inotify lcms2 dynamic-setting
system-font-setting font-render-setting cairo move-toolbar gtk x-toolkit
xinput2 x multi-tty make-network-process native-compile emacs)

Memory information:
((conses 16 2024913 273749)
 (symbols 48 87084 3)
 (strings 32 411062 19869)
 (string-bytes 1 13274489)
 (vectors 16 177648)
 (vector-slots 8 3980527 231548)
 (floats 8 2606 580)
 (intervals 56 25524 1236)
 (buffers 984 96))