'dd' with whitespace-mode sometimes raises 'wrong-type-argument wholenump -[integer]'
This has been driving me insane for a while. I first thought it was a spacemacs problem but it turned out to be an "Evil" related issue.
This is a copy/paste from the cross issue:
When placed on a whitespace character at the beginning of the line, using dd to delete a line (or yy to yank, gcc to comment, likely more) results in the error wrong-type-argument wholenump -5. This does not happen with D.
This seemingly only happens with whitespace-mode enabled. I tried debugging with only evil and whitespace-mode (using make emacs in a fresh evil source dir) and did not encounter this issue even with the same reproduction method.
I can't confirm this, but after testing for a minute or so it seems like this only happens when the line contains or is immediately preceded or followed by "invalid" whitespace (e.g. a line containing only non-newline whitespace or that has trailing whitespace).
After more testing, I have determined that the error occurs when either
1. Trying to perform such an action on a line when the cursor is placed on a whitespace character in column 0. In this case, the error is random and I sometimes have to keep undoing the action (in case of deleting), moving back and forth between lines, and trying again in order to encounter it.
2. Trying to perform such an action after moving the cursor up or down off of the second whitespace character in a line and not having moved left or right. When the cursor is first moved up or down, it will jump to column 0. With this method, the error occurs every time.
Thanks for cross-reporting!
See here for the issue reported in the spacemacs repo. Slightly more details there.
I believe this might be a bug in Emacs itself.
I run into this error most frequently when jumping up and down a buffer via C-u and C-d. Evil's evil-ensure-column uses temporary-goal-column to calculate the column to jump to. In some cases the value for temporary-goal-column occasionally gets set to (-5 . 0) (or similar), and evil-ensure-column will normalize that to -5 when calling line-move-to-column.
The only place where I can find that would set a cons pair with a possibly negative value for temporary-goal-column was at https://github.com/emacs-mirror/emacs/blob/9370a4763aacbb9278b5be9c92a2484e3652bc29/lisp/simple.el#L7388-L7391.
Every time I got the wholenump error, I evaluated the following via M-: and got -5 back:
(/ (float (- (car (posn-x-y (posn-at-point)))
(line-number-display-width t)))
(frame-char-width))
This is the same expression as what's in the above link, just without the intermediate variables.
In most cases, I get 65 when evaluating (car (posn-x-y (posn-at-point))) when my cursor is at the beginning of a line. I also get 65 when evaluating (line-number-display-width t). However, I'll occasionally get 0 for (car (posn-x-y (posn-at-point))) which would explain the negative value. I don't know enough about the Emacs code base to understand why this expressions returns 0 sometimes. I saw that @Eli-Zaretskii has touched that part of the code base most recently, so they might be able to chime in.
I'm on Emacs 28.1, haven't had a chance to test against other versions of emacs. I also don't have reproduction steps other than continually pressing C-u to reach the top of a buffer then continually pressing C-d to reach the bottom. Eventually the the "wholenump" error shows up.
Edit
I think this is an issue with whitespace-mode. With whitespace mode turned off, I get 65 when evaluating (car (posn-x-y (posn-at-point))) at the beginning of a line. With it turned on, I'll get 65 if I'm on a non-empty line, but get 0 when I'm on an empty line. I have not ran into the wholenump error yet with whitespace-mode turned off.
If you can come up with a simple enough recipe starting with emacs -Q and demonstrating the issue with whitespace-mode, I will look into it.
Hi Eli, thanks for responding.
As a clarifying question, should we ever expect temporary-goal-column to contain negative values? If not, I have a small reproduction showing how to get negative values.
Setup, paste and eval the following in a buffer (with emacs -Q):
;; Repro
(display-line-numbers-mode 1)
(whitespace-mode 1)
- Go to line 2 (beginning of the empty line). Describe
temporary-goal-column, observe non-negative values. - Press
C-n(moving to line 3). Describetemporary-goal-column, observe the value(-4.0 . 0)(or a similar negative value).
When disabling display-line-numbers-mode or whitespace-mode, I never get negative values when describing temporary-goal-column.
Some additional info:
- Emacs 28.1(from the Arch repos)
- I can reproduce both in the gui and terminal.
Let me know if there's more info needed.
I cannot reproduce the problem, with the above recipe, neither in Emacs 28.1 nor with the current master branch of the Emacs Git repository. I always get zero value of temporary-goal-column after C-n.
Perhaps the recipe is not detailed enough, and I didn't perform exactly the same steps as you did? For example, in which buffer to paste those 4 lines, and how to evaluate them? IOW, please try to show a more detailed, step-by-step, recipe, with all the commands and key sequences explicitly mentioned.
Hi Eli, more detailed steps below.
- Save the following to some file (I chose
/tmp/repro.el):
;; Repro
(global-display-line-numbers-mode 1)
(global-whitespace-mode 1)
- Load and open the file:
emacs -Q -l /tmp/repro.el /tmp/repro.el C-n,C-h v temporary-goal-column- Cursor should be at the beginning of line 2 (empty line) after these key presses.
- This shows
(0.0 . 0).
C-n,C-h v temporary-goal-column- Cursor should be at the beginning of line 3 after these key presses.
- This shows
(-4.0 . 0)fortemporary-goal-column.
I'm able to reproduce with these exact steps. I do not execute anything else in emacs beyond the sequences shown in steps 3 and 4.
I was also able to reproduce on this on master using the above steps. Build details below:
Configured features: ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG JSON LCMS2 LIBOTF LIBSYSTEMD LIBXML2 M17N_FLT MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB
Important settings: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix
Major mode: ELisp/d
Minor modes in effect: global-whitespace-mode: t global-display-line-numbers-mode: t display-line-numbers-mode: t tooltip-mode: t global-eldoc-mode: t eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-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: None found.
Features: (shadow sort mail-extr emacsbug message mailcap yank-media rmc puny dired dired-loaddefs rfc822 mml mml-sec password-cache epa derived epg rfc6068 epg-config gnus-util text-property-search time-date mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils seq gv subr-x byte-opt bytecomp byte-compile cconv disp-table whitespace display-line-numbers iso-transl tooltip 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 simple cl-generic 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 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 lcms2 dynamic-setting system-font-setting font-render-setting cairo move-toolbar gtk x-toolkit xinput2 x multi-tty make-network-process emacs)
Memory information: ((conses 16 45006 6837) (symbols 48 5859 1) (strings 32 16158 1605) (string-bytes 1 541329) (vectors 16 11268) (vector-slots 8 164111 10898) (floats 8 21 41) (intervals 56 234 0) (buffers 992 12))
Sorry, still not reproducible.
Does this happen for you with any font and any font size? Or does it only happen for some fonts/sizes?
If it happens for any font, then I have no idea why I cannot reproduce this.
This seems to happen no matter the font or font size I pick. Specifically I ran each of these expressions in turn and repeated the above steps:
(set-face-attribute 'default nil :family "PragmataPro Mono" :height 120 :weight 'normal)
(set-face-attribute 'default nil :family "PragmataPro Mono" :height 100 :weight 'normal)
(set-face-attribute 'default nil :family "Source Code Pro" :height 120 :weight 'normal)
(set-face-attribute 'default nil :family "Source Code Pro" :height 100 :weight 'normal)
(set-face-attribute 'default nil :family "Fira Mono" :height 120 :weight 'normal)
(set-face-attribute 'default nil :family "Fira Mono" :height 100 :weight 'normal)
To make sure it wasn't something with Arch, I spun up an Ubuntu 22.04 vm on Google Cloud and installed emacs via apt update && apt install emacs on that vm. Below is a short mp4 showing a reproduction on that vm using the steps I've listed above.
https://user-images.githubusercontent.com/4040560/168129862-33de4d07-c76b-48c4-968d-4a3bbe302a09.mp4
I believe you. I just cannot reproduce this on my machine, and without that I cannot debug this.
I even tried Source Code Pro font, and still no cigar. Sorry.
No worries, the linked PR fixes the immediate issue with evil passing around negative numbers, so that's probably good enough for now.
When I have time, I'll try to dive in deeper into them emacs code base and see what's up.