GNU bug report logs - #77465
29.4; VC annotate does not display tabs properly

Previous Next

Package: emacs;

Reported by: Tom Tromey <tromey <at> adacore.com>

Date: Wed, 2 Apr 2025 16:32:01 UTC

Severity: normal

Found in version 29.4

To reply to this bug, email your comments to 77465 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#77465; Package emacs. (Wed, 02 Apr 2025 16:32:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Tom Tromey <tromey <at> adacore.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 02 Apr 2025 16:32:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Tom Tromey <tromey <at> adacore.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 29.4; VC annotate does not display tabs properly
Date: Wed, 02 Apr 2025 10:30:57 -0600
Some projects I work on use tab characters for indentation.
I used 'C-x v =' to annotate a file from one of these projects.

In this case, because the VC-provided margin text is not a multiple of 8
characters, the tabs are rendered improperly, making the program text
look strange.

As an example, open emacs/src/alloc.c and C-x v =

Then search for the tab character in code (with comments the weirdness
isn't as pronounced).

Here's an example from emacs where I've turned the tabs into spaces so
you can see the effect:

b88e9cded7ae (Paul Eggert             2016-01-26  226)   else
b88e9cded7ae (Paul Eggert             2016-01-26  227)     {
b88e9cded7ae (Paul Eggert             2016-01-26  228)       if (!malloc_using_checking)
b88e9cded7ae (Paul Eggert             2016-01-26  229)  {
b88e9cded7ae (Paul Eggert             2016-01-26  230)    /* Work around a bug in glibc's malloc.  MALLOC_CHECK_ must be


One simple fix would be to ensure that the margin text is always a
multiple of 8.  However, a more sophisticated approach may be possible
as well.



In GNU Emacs 29.4 (build 1, x86_64-redhat-linux-gnu, GTK+ Version
 3.24.43, cairo version 1.18.2) of 2025-03-13 built on
 0cbb79ebeb714371b64bef3269323882
System Description: Fedora Linux 41 (Workstation Edition)

Configured using:
 'configure --build=x86_64-redhat-linux-gnu
 --host=x86_64-redhat-linux-gnu --program-prefix=
 --disable-dependency-tracking --prefix=/usr --exec-prefix=/usr
 --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc
 --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib64
 --libexecdir=/usr/libexec --localstatedir=/var --runstatedir=/run
 --sharedstatedir=/var/lib --mandir=/usr/share/man
 --infodir=/usr/share/info --with-cairo --with-dbus --with-gif
 --with-gpm=no --with-harfbuzz --with-jpeg --with-json --with-modules
 --with-native-compilation=aot --with-pgtk --with-png --with-rsvg
 --with-sqlite3 --with-tiff --with-tree-sitter --with-webp --with-xpm
 build_alias=x86_64-redhat-linux-gnu host_alias=x86_64-redhat-linux-gnu
 CC=gcc 'CFLAGS=-DMAIL_USE_LOCKF -O2 -flto=auto -ffat-lto-objects
 -fexceptions -g -grecord-gcc-switches -pipe -Wall
 -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3
 -Wp,-D_GLIBCXX_ASSERTIONS
 -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong
 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64
 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection
 -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer
 -mno-omit-leaf-frame-pointer ' 'LDFLAGS=-Wl,-z,relro -Wl,--as-needed
 -Wl,-z,pack-relative-relocs -Wl,-z,now
 -specs=/usr/lib/rpm/redhat/redhat-hardened-ld
 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1
 -specs=/usr/lib/rpm/redhat/redhat-package-notes '
 PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig CXX=g++
 'CXXFLAGS=-O2 -flto=auto -ffat-lto-objects -fexceptions -g
 -grecord-gcc-switches -pipe -Wall -Werror=format-security
 -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS
 -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong
 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64
 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection
 -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer
 -mno-omit-leaf-frame-pointer ''

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY
PDUMPER PGTK PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP XIM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: Annotate

Minor modes in effect:
  shell-dirtrack-mode: t
  which-function-mode: t
  erc-services-mode: t
  erc-networks-mode: t
  server-mode: t
  savehist-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
  buffer-read-only: t
  column-number-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/home/tromey/.emacs.d/elpa/ggtags-0.9.0/ggtags hides /home/tromey/.emacs.d/elpa/ggtags-0.8.13/ggtags
/home/tromey/.emacs.d/elpa/ggtags-0.9.0/ggtags-pkg hides /home/tromey/.emacs.d/elpa/ggtags-0.8.13/ggtags-pkg
/home/tromey/.emacs.d/elpa/ggtags-0.9.0/ggtags-autoloads hides /home/tromey/.emacs.d/elpa/ggtags-0.8.13/ggtags-autoloads

Features:
(shadow bbdb-message mailalias mail-hist emacsbug sh-script smie
executable dabbrev goto-addr log-edit python ada-ts-mode-lspclient-eglot
ada-ts-mode ada-ts-indentation ada-ts-casing eglot external-completion
array jsonrpc ert debug backtrace flymake-proc flymake
ada-ts-mode-lspclient treesit ada-ts-mode-autoloads noutline outline
ggtags-autoloads loaddefs-gen tar-mode arc-mode archive-mode cus-edit
cus-start package-vc lisp-mnt url-http url-auth url-gw
display-line-numbers gud vc-annotate copyright vc-hg vc-bzr vc-src
vc-sccs vc-svn vc-cvs vc-rcs log-view pcvs-util conf-mode term/xterm
xterm mule-util ggtags hippie-exp etags fileloop generator xref project
bug-reference vc-git cc-mode cc-fonts cc-guess cc-menus cc-cmds add-log
flow-fill smerge-mode diff diff-mode gnus-html url-queue help-fns
radix-tree url-cache mm-url sort smiley gnus-cite mm-archive mail-extr
textsec uni-scripts idna-mapping ucs-normalize uni-confusable
textsec-check gnus-bcklg gnus-async qp gnus-ml disp-table misearch
multi-isearch gnus-topic nndraft nnmh nnfolder utf-7 bbdb-gnus bbdb-mua
bbdb-com crm network-stream nsm gnus-agent gnus-srvr gnus-score
score-mode nnvirtual gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime
smime gnutls dig nntp gnus-cache gnus-sum shr pixel-fill kinsoku
url-file svg dom gnus-group gnus-undo smtpmail gnus-start gnus-dbus
gnus-cloud nnimap nnmail mail-source utf7 nnoo gnus-spec gnus-int
gnus-range message sendmail yank-media puny rfc822 mml mml-sec epa epg
rfc6068 epg-config mm-decode mm-bodies mm-encode mail-parse rfc2231
rfc2047 rfc2045 ietf-drums mailabbrev gmm-utils mailheader gnus-win gnus
nnheader gnus-util mail-utils range mm-util mail-prsvr
display-fill-column-indicator flyspell ispell diminish appt diary-lib
diary-loaddefs cal-menu calendar cal-loaddefs tramp tramp-loaddefs
trampver tramp-integration files-x tramp-compat shell pcomplete
parse-time which-func imenu autorevert filenotify desktop frameset
cus-load git-link erc-track erc-notify erc-desktop-notifications
erc-match erc-services notifications dbus erc-hl-nicks color erc-button
erc-fill erc-stamp wid-edit erc-goodies erc iso8601 time-date thingatpt
pp format-spec erc-backend erc-networks erc-common erc-compat compat
erc-loaddefs dired-aux dired-x dired dired-loaddefs comp comp-cstr
cl-extra warnings icons advice vc-dir ewoc vc vc-dispatcher flycheck
easy-mmode find-func help-mode rx dash cl pcase jka-compr compile
text-property-search cc-styles cc-align cc-engine cc-vars cc-defs bbdb
derived bbdb-site timezone ange-ftp comint ansi-osc ansi-color ring
server savehist finder-inf clang-rename clang-include-fixer let-alist
clang-format xml 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/pgtk-win pgtk-win term/common-win pgtk-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 dbusbind
inotify dynamic-setting system-font-setting font-render-setting cairo
gtk pgtk multi-tty make-network-process native-compile emacs)

Memory information:
((conses 16 1300064 422488)
 (symbols 48 57113 1)
 (strings 32 496408 8613)
 (string-bytes 1 13434307)
 (vectors 16 168369)
 (vector-slots 8 3590796 73717)
 (floats 8 506 768)
 (intervals 56 34255 18946)
 (buffers 984 93))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#77465; Package emacs. (Thu, 03 Apr 2025 07:48:01 GMT) Full text and rfc822 format available.

Message #8 received at 77465 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Tom Tromey <tromey <at> adacore.com>
Cc: 77465 <at> debbugs.gnu.org
Subject: Re: bug#77465: 29.4; VC annotate does not display tabs properly
Date: Thu, 03 Apr 2025 10:47:17 +0300
> Date: Wed, 02 Apr 2025 10:30:57 -0600
> From:  Tom Tromey via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org>
> 
> 
> Some projects I work on use tab characters for indentation.

Emacs uses TABs mixed with SPCes as a matter of policy.

> I used 'C-x v =' to annotate a file from one of these projects.
> 
> In this case, because the VC-provided margin text is not a multiple of 8
> characters, the tabs are rendered improperly, making the program text
> look strange.
> 
> As an example, open emacs/src/alloc.c and C-x v =
> 
> Then search for the tab character in code (with comments the weirdness
> isn't as pronounced).
> 
> Here's an example from emacs where I've turned the tabs into spaces so
> you can see the effect:
> 
> b88e9cded7ae (Paul Eggert             2016-01-26  226)   else
> b88e9cded7ae (Paul Eggert             2016-01-26  227)     {
> b88e9cded7ae (Paul Eggert             2016-01-26  228)       if (!malloc_using_checking)
> b88e9cded7ae (Paul Eggert             2016-01-26  229)  {
> b88e9cded7ae (Paul Eggert             2016-01-26  230)    /* Work around a bug in glibc's malloc.  MALLOC_CHECK_ must be

AFAICT, "git annotate" produces the same effect when invoked from the
shell prompt.  I'm not sure we should try to be "holier than the Pope"
here.

> One simple fix would be to ensure that the margin text is always a
> multiple of 8.

I don't think this is practical, since Git doesn't guarantee the
prefix of a line to be of a fixed width.  Here's a typical example:

47099d6f7       (Richard M. Stallman    1993-06-06 21:16:51 +0000       27)
4588ec205       (Jim Blandy     1991-07-03 12:10:07 +0000       28)
a08795204       (Richard M. Stallman    1995-11-12 05:20:12 +0000       29)
fd2e066a8       (Geoff Voelker  1995-11-07 07:14:59 +0000       30)
fd2e066a8       (Geoff Voelker  1995-11-07 07:14:59 +0000       31)
e5560ff7d       (Andreas Schwab 2012-06-16 14:24:15 +0200       32)
d43721a22       (Andrew Innes   2000-08-22 22:14:00 +0000       33)
502b9b644       (Jim Blandy     1992-07-13 19:54:34 +0000       34)
428a555ec       (Károly Lőrentey        2004-01-05 05:54:35 +0000       35)
4588ec205       (Jim Blandy     1991-07-03 12:10:07 +0000       36)
4588ec205       (Jim Blandy     1991-07-03 12:10:07 +0000       37)
4588ec205       (Jim Blandy     1991-07-03 12:10:07 +0000       38)
97cf50e75       (Richard M. Stallman    1996-04-23 20:32:58 +0000       39)
58b2bb63f       (Richard M. Stallman    1995-08-21 21:56:40 +0000       40)

> However, a more sophisticated approach may be possible as well.

The only idea I have is to replace each tab with a suitable number of
spaces, but that would probably make this command much slower, since
the buffer created by "C-x v =" is typically very large.

Any other ideas?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#77465; Package emacs. (Thu, 03 Apr 2025 14:57:02 GMT) Full text and rfc822 format available.

Message #11 received at 77465 <at> debbugs.gnu.org (full text, mbox):

From: Tom Tromey <tromey <at> adacore.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 77465 <at> debbugs.gnu.org, Tom Tromey <tromey <at> adacore.com>
Subject: Re: bug#77465: 29.4; VC annotate does not display tabs properly
Date: Thu, 03 Apr 2025 08:56:12 -0600
>> b88e9cded7ae (Paul Eggert             2016-01-26  230)    /* Work around a bug in glibc's malloc.  MALLOC_CHECK_ must be

Eli> AFAICT, "git annotate" produces the same effect when invoked from the
Eli> shell prompt.  I'm not sure we should try to be "holier than the Pope"
Eli> here.

I see it as being along the line of font-locking the annotation buffer
by age -- it's a display feature to help make the output more readable.
That is, git may do the wrong thing but Emacs doesn't have to.

>> One simple fix would be to ensure that the margin text is always a
>> multiple of 8.

Eli> I don't think this is practical, since Git doesn't guarantee the
Eli> prefix of a line to be of a fixed width.

I didn't realize that.

>> However, a more sophisticated approach may be possible as well.

Eli> The only idea I have is to replace each tab with a suitable number of
Eli> spaces, but that would probably make this command much slower, since
Eli> the buffer created by "C-x v =" is typically very large.

Eli> Any other ideas?

It's been a long time since I dug into this kind of thing but I was
wondering if there is some kind of display and/or text property feature
that would help.

Maybe putting a :align-to on the space following the ")" would help.

Note that, at least in the repositories I use, annotation display is
already slow enough (presumably due to extensive history in git) that
another minor slowdown to find the correct width would not really be
noticeable.

Tom




This bug report was last modified 8 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.