unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
@ 2014-12-04  8:06 Tassilo Horn
  2022-05-12  2:16 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2014-12-04  8:06 UTC (permalink / raw)
  To: 19267


I like the new `cycle-spacing' command but I frequently would like to
have an additional space where only the whitespace after point is
deleted.  That'd be useful when manually formatting text (code) where
auto-indentation isn't available.  My prime use-case is laying out
example code snippets in comments and docstrings which I copied & pasted
from somewhere else.  E.g., I start with a docstring

  "Example:

     (let [x :something]
       |                  (foo x)
                          (bar x))"

where | is the position of point.  In that case, I'd like if M-SPC would
change the text to

  "Example:

     (let [x :something]
       |(foo x)
                          (bar x))"

instead of

  "Example:

     (let [x :something]
 |(foo x)
                          (bar x))"

i.e., it first M-SPC only deletes whitespace after point but not before.
I don't really care if that's the first state (although that would be
plausible, i.e., states are cycled from more space to less spaces), but
at least it should be a reachable state.



In GNU Emacs 25.0.50.3 (x86_64-unknown-linux-gnu, GTK+ Version 3.14.5)
 of 2014-12-04 on thinkpad-t440p
Repository revision: a0363ffa9931cf751a92577ab1b0a7acbae4c4e7
Windowing system distributor `The X.Org Foundation', version 11.0.11602000
System Description:	Arch Linux

Configured features:
XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GCONF GSETTINGS
NOTIFY ACL GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB

Important settings:
  value of $LC_MONETARY: de_DE.utf8
  value of $LC_NUMERIC: de_DE.utf8
  value of $LC_TIME: de_DE.utf8
  value of $LANG: en_US.utf8
  locale-coding-system: utf-8-unix

Major mode: rcirc

Minor modes in effect:
  rcirc-track-minor-mode: t
  diff-auto-refine-mode: t
  TeX-PDF-mode: t
  TeX-source-correlate-mode: t
  global-company-mode: t
  global-aggressive-indent-mode: t
  aggressive-indent-mode: t
  global-edit-server-edit-mode: t
  recentf-mode: t
  shell-dirtrack-mode: t
  helm-match-plugin-mode: t
  helm-occur-match-plugin-mode: t
  global-subword-mode: t
  subword-mode: t
  savehist-mode: t
  show-paren-mode: t
  icomplete-mode: t
  minibuffer-depth-indicate-mode: t
  electric-pair-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  use-hard-newlines: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t

Recent messages:
=> #'funnyqt.pmatch-test/test-eager-pattern-generic
Type "q" in help window to delete it
nil
Connecting to irc.freenode.net...
Rcirc-Omit mode enabled
Connecting to irc.freenode.net...done
Quit
Rcirc-Omit mode enabled [11 times]
Auto-saving...done
Using try-complete-lisp-symbol
Quit

Load-path shadows:
~/Repos/el/auctex/lpath hides ~/Repos/el/gnus/lisp/lpath
~/Repos/el/gnus/lisp/md4 hides /home/horn/Repos/el/emacs/lisp/md4
~/Repos/el/gnus/lisp/color hides /home/horn/Repos/el/emacs/lisp/color
~/Repos/el/gnus/lisp/format-spec hides /home/horn/Repos/el/emacs/lisp/format-spec
~/Repos/el/gnus/lisp/password-cache hides /home/horn/Repos/el/emacs/lisp/password-cache
~/Repos/el/gnus/lisp/hex-util hides /home/horn/Repos/el/emacs/lisp/hex-util
~/Repos/el/gnus/lisp/dns-mode hides /home/horn/Repos/el/emacs/lisp/textmodes/dns-mode
/home/horn/.emacs.d/elpa/org-20141201/ob-plantuml hides /home/horn/Repos/el/emacs/lisp/org/ob-plantuml
/home/horn/.emacs.d/elpa/org-20141201/org-archive hides /home/horn/Repos/el/emacs/lisp/org/org-archive
/home/horn/.emacs.d/elpa/org-20141201/org-w3m hides /home/horn/Repos/el/emacs/lisp/org/org-w3m
/home/horn/.emacs.d/elpa/org-20141201/ox-org hides /home/horn/Repos/el/emacs/lisp/org/ox-org
/home/horn/.emacs.d/elpa/org-20141201/ob hides /home/horn/Repos/el/emacs/lisp/org/ob
/home/horn/.emacs.d/elpa/org-20141201/org-faces hides /home/horn/Repos/el/emacs/lisp/org/org-faces
/home/horn/.emacs.d/elpa/org-20141201/ob-awk hides /home/horn/Repos/el/emacs/lisp/org/ob-awk
/home/horn/.emacs.d/elpa/org-20141201/org-habit hides /home/horn/Repos/el/emacs/lisp/org/org-habit
/home/horn/.emacs.d/elpa/org-20141201/ob-sass hides /home/horn/Repos/el/emacs/lisp/org/ob-sass
/home/horn/.emacs.d/elpa/org-20141201/org-ctags hides /home/horn/Repos/el/emacs/lisp/org/org-ctags
/home/horn/.emacs.d/elpa/org-20141201/ob-screen hides /home/horn/Repos/el/emacs/lisp/org/ob-screen
/home/horn/.emacs.d/elpa/org-20141201/ox-md hides /home/horn/Repos/el/emacs/lisp/org/ox-md
/home/horn/.emacs.d/elpa/org-20141201/ox-beamer hides /home/horn/Repos/el/emacs/lisp/org/ox-beamer
/home/horn/.emacs.d/elpa/org-20141201/org-loaddefs hides /home/horn/Repos/el/emacs/lisp/org/org-loaddefs
/home/horn/.emacs.d/elpa/org-20141201/ob-perl hides /home/horn/Repos/el/emacs/lisp/org/ob-perl
/home/horn/.emacs.d/elpa/org-20141201/org-rmail hides /home/horn/Repos/el/emacs/lisp/org/org-rmail
/home/horn/.emacs.d/elpa/org-20141201/org-id hides /home/horn/Repos/el/emacs/lisp/org/org-id
/home/horn/.emacs.d/elpa/org-20141201/ox-publish hides /home/horn/Repos/el/emacs/lisp/org/ox-publish
/home/horn/.emacs.d/elpa/org-20141201/ob-maxima hides /home/horn/Repos/el/emacs/lisp/org/ob-maxima
/home/horn/.emacs.d/elpa/org-20141201/org-install hides /home/horn/Repos/el/emacs/lisp/org/org-install
/home/horn/.emacs.d/elpa/org-20141201/org-feed hides /home/horn/Repos/el/emacs/lisp/org/org-feed
/home/horn/.emacs.d/elpa/org-20141201/ob-R hides /home/horn/Repos/el/emacs/lisp/org/ob-R
/home/horn/.emacs.d/elpa/org-20141201/ox-latex hides /home/horn/Repos/el/emacs/lisp/org/ox-latex
/home/horn/.emacs.d/elpa/org-20141201/org-timer hides /home/horn/Repos/el/emacs/lisp/org/org-timer
/home/horn/.emacs.d/elpa/org-20141201/ob-core hides /home/horn/Repos/el/emacs/lisp/org/ob-core
/home/horn/.emacs.d/elpa/org-20141201/org-datetree hides /home/horn/Repos/el/emacs/lisp/org/org-datetree
/home/horn/.emacs.d/elpa/org-20141201/ob-sql hides /home/horn/Repos/el/emacs/lisp/org/ob-sql
/home/horn/.emacs.d/elpa/org-20141201/ob-js hides /home/horn/Repos/el/emacs/lisp/org/ob-js
/home/horn/.emacs.d/elpa/org-20141201/ob-tangle hides /home/horn/Repos/el/emacs/lisp/org/ob-tangle
/home/horn/.emacs.d/elpa/org-20141201/org-capture hides /home/horn/Repos/el/emacs/lisp/org/org-capture
/home/horn/.emacs.d/elpa/org-20141201/ob-haskell hides /home/horn/Repos/el/emacs/lisp/org/ob-haskell
/home/horn/.emacs.d/elpa/org-20141201/ob-dot hides /home/horn/Repos/el/emacs/lisp/org/ob-dot
/home/horn/.emacs.d/elpa/org-20141201/ob-exp hides /home/horn/Repos/el/emacs/lisp/org/ob-exp
/home/horn/.emacs.d/elpa/org-20141201/org-info hides /home/horn/Repos/el/emacs/lisp/org/org-info
/home/horn/.emacs.d/elpa/org-20141201/ob-octave hides /home/horn/Repos/el/emacs/lisp/org/ob-octave
/home/horn/.emacs.d/elpa/org-20141201/org-mobile hides /home/horn/Repos/el/emacs/lisp/org/org-mobile
/home/horn/.emacs.d/elpa/org-20141201/org-indent hides /home/horn/Repos/el/emacs/lisp/org/org-indent
/home/horn/.emacs.d/elpa/org-20141201/org-attach hides /home/horn/Repos/el/emacs/lisp/org/org-attach
/home/horn/.emacs.d/elpa/org-20141201/ob-java hides /home/horn/Repos/el/emacs/lisp/org/ob-java
/home/horn/.emacs.d/elpa/org-20141201/org-mhe hides /home/horn/Repos/el/emacs/lisp/org/org-mhe
/home/horn/.emacs.d/elpa/org-20141201/ob-scheme hides /home/horn/Repos/el/emacs/lisp/org/ob-scheme
/home/horn/.emacs.d/elpa/org-20141201/ob-lob hides /home/horn/Repos/el/emacs/lisp/org/ob-lob
/home/horn/.emacs.d/elpa/org-20141201/ob-calc hides /home/horn/Repos/el/emacs/lisp/org/ob-calc
/home/horn/.emacs.d/elpa/org-20141201/org-agenda hides /home/horn/Repos/el/emacs/lisp/org/org-agenda
/home/horn/.emacs.d/elpa/org-20141201/org-version hides /home/horn/Repos/el/emacs/lisp/org/org-version
/home/horn/.emacs.d/elpa/org-20141201/org-clock hides /home/horn/Repos/el/emacs/lisp/org/org-clock
/home/horn/.emacs.d/elpa/org-20141201/org-macro hides /home/horn/Repos/el/emacs/lisp/org/org-macro
/home/horn/.emacs.d/elpa/org-20141201/ob-fortran hides /home/horn/Repos/el/emacs/lisp/org/ob-fortran
/home/horn/.emacs.d/elpa/org-20141201/ob-picolisp hides /home/horn/Repos/el/emacs/lisp/org/ob-picolisp
/home/horn/.emacs.d/elpa/org-20141201/ob-mscgen hides /home/horn/Repos/el/emacs/lisp/org/ob-mscgen
/home/horn/.emacs.d/elpa/org-20141201/ox-texinfo hides /home/horn/Repos/el/emacs/lisp/org/ox-texinfo
/home/horn/.emacs.d/elpa/org-20141201/org-table hides /home/horn/Repos/el/emacs/lisp/org/org-table
/home/horn/.emacs.d/elpa/org-20141201/ob-matlab hides /home/horn/Repos/el/emacs/lisp/org/ob-matlab
/home/horn/.emacs.d/elpa/org-20141201/ox-html hides /home/horn/Repos/el/emacs/lisp/org/ox-html
/home/horn/.emacs.d/elpa/org-20141201/ox-icalendar hides /home/horn/Repos/el/emacs/lisp/org/ox-icalendar
/home/horn/.emacs.d/elpa/org-20141201/org-bbdb hides /home/horn/Repos/el/emacs/lisp/org/org-bbdb
/home/horn/.emacs.d/elpa/org-20141201/ob-asymptote hides /home/horn/Repos/el/emacs/lisp/org/ob-asymptote
/home/horn/.emacs.d/elpa/org-20141201/org-eshell hides /home/horn/Repos/el/emacs/lisp/org/org-eshell
/home/horn/.emacs.d/elpa/org-20141201/ob-comint hides /home/horn/Repos/el/emacs/lisp/org/ob-comint
/home/horn/.emacs.d/elpa/org-20141201/org hides /home/horn/Repos/el/emacs/lisp/org/org
/home/horn/.emacs.d/elpa/org-20141201/org-irc hides /home/horn/Repos/el/emacs/lisp/org/org-irc
/home/horn/.emacs.d/elpa/org-20141201/ob-table hides /home/horn/Repos/el/emacs/lisp/org/ob-table
/home/horn/.emacs.d/elpa/org-20141201/ob-scala hides /home/horn/Repos/el/emacs/lisp/org/ob-scala
/home/horn/.emacs.d/elpa/org-20141201/ob-io hides /home/horn/Repos/el/emacs/lisp/org/ob-io
/home/horn/.emacs.d/elpa/org-20141201/ox-ascii hides /home/horn/Repos/el/emacs/lisp/org/ox-ascii
/home/horn/.emacs.d/elpa/org-20141201/ob-lisp hides /home/horn/Repos/el/emacs/lisp/org/ob-lisp
/home/horn/.emacs.d/elpa/org-20141201/org-macs hides /home/horn/Repos/el/emacs/lisp/org/org-macs
/home/horn/.emacs.d/elpa/org-20141201/ob-sqlite hides /home/horn/Repos/el/emacs/lisp/org/ob-sqlite
/home/horn/.emacs.d/elpa/org-20141201/ob-latex hides /home/horn/Repos/el/emacs/lisp/org/ob-latex
/home/horn/.emacs.d/elpa/org-20141201/ob-css hides /home/horn/Repos/el/emacs/lisp/org/ob-css
/home/horn/.emacs.d/elpa/org-20141201/org-protocol hides /home/horn/Repos/el/emacs/lisp/org/org-protocol
/home/horn/.emacs.d/elpa/org-20141201/ob-keys hides /home/horn/Repos/el/emacs/lisp/org/ob-keys
/home/horn/.emacs.d/elpa/org-20141201/org-mouse hides /home/horn/Repos/el/emacs/lisp/org/org-mouse
/home/horn/.emacs.d/elpa/org-20141201/ob-ruby hides /home/horn/Repos/el/emacs/lisp/org/ob-ruby
/home/horn/.emacs.d/elpa/org-20141201/org-element hides /home/horn/Repos/el/emacs/lisp/org/org-element
/home/horn/.emacs.d/elpa/org-20141201/org-bibtex hides /home/horn/Repos/el/emacs/lisp/org/org-bibtex
/home/horn/.emacs.d/elpa/org-20141201/ob-C hides /home/horn/Repos/el/emacs/lisp/org/ob-C
/home/horn/.emacs.d/elpa/org-20141201/org-src hides /home/horn/Repos/el/emacs/lisp/org/org-src
/home/horn/.emacs.d/elpa/org-20141201/ob-makefile hides /home/horn/Repos/el/emacs/lisp/org/ob-makefile
/home/horn/.emacs.d/elpa/org-20141201/org-colview hides /home/horn/Repos/el/emacs/lisp/org/org-colview
/home/horn/.emacs.d/elpa/org-20141201/ob-ledger hides /home/horn/Repos/el/emacs/lisp/org/ob-ledger
/home/horn/.emacs.d/elpa/org-20141201/org-crypt hides /home/horn/Repos/el/emacs/lisp/org/org-crypt
/home/horn/.emacs.d/elpa/org-20141201/ob-shen hides /home/horn/Repos/el/emacs/lisp/org/ob-shen
/home/horn/.emacs.d/elpa/org-20141201/ob-gnuplot hides /home/horn/Repos/el/emacs/lisp/org/ob-gnuplot
/home/horn/.emacs.d/elpa/org-20141201/org-inlinetask hides /home/horn/Repos/el/emacs/lisp/org/org-inlinetask
/home/horn/.emacs.d/elpa/org-20141201/org-gnus hides /home/horn/Repos/el/emacs/lisp/org/org-gnus
/home/horn/.emacs.d/elpa/org-20141201/ob-sh hides /home/horn/Repos/el/emacs/lisp/org/ob-sh
/home/horn/.emacs.d/elpa/org-20141201/org-pcomplete hides /home/horn/Repos/el/emacs/lisp/org/org-pcomplete
/home/horn/.emacs.d/elpa/org-20141201/org-docview hides /home/horn/Repos/el/emacs/lisp/org/org-docview
/home/horn/.emacs.d/elpa/org-20141201/ox-man hides /home/horn/Repos/el/emacs/lisp/org/ox-man
/home/horn/.emacs.d/elpa/org-20141201/org-plot hides /home/horn/Repos/el/emacs/lisp/org/org-plot
/home/horn/.emacs.d/elpa/org-20141201/ox hides /home/horn/Repos/el/emacs/lisp/org/ox
/home/horn/.emacs.d/elpa/org-20141201/ob-python hides /home/horn/Repos/el/emacs/lisp/org/ob-python
/home/horn/.emacs.d/elpa/org-20141201/ob-eval hides /home/horn/Repos/el/emacs/lisp/org/ob-eval
/home/horn/.emacs.d/elpa/org-20141201/ob-clojure hides /home/horn/Repos/el/emacs/lisp/org/ob-clojure
/home/horn/.emacs.d/elpa/org-20141201/ob-ocaml hides /home/horn/Repos/el/emacs/lisp/org/ob-ocaml
/home/horn/.emacs.d/elpa/org-20141201/ox-odt hides /home/horn/Repos/el/emacs/lisp/org/ox-odt
/home/horn/.emacs.d/elpa/org-20141201/org-compat hides /home/horn/Repos/el/emacs/lisp/org/org-compat
/home/horn/.emacs.d/elpa/org-20141201/org-list hides /home/horn/Repos/el/emacs/lisp/org/org-list
/home/horn/.emacs.d/elpa/org-20141201/ob-emacs-lisp hides /home/horn/Repos/el/emacs/lisp/org/ob-emacs-lisp
/home/horn/.emacs.d/elpa/org-20141201/org-entities hides /home/horn/Repos/el/emacs/lisp/org/org-entities
/home/horn/.emacs.d/elpa/org-20141201/ob-ref hides /home/horn/Repos/el/emacs/lisp/org/ob-ref
/home/horn/.emacs.d/elpa/org-20141201/ob-ditaa hides /home/horn/Repos/el/emacs/lisp/org/ob-ditaa
/home/horn/.emacs.d/elpa/org-20141201/ob-lilypond hides /home/horn/Repos/el/emacs/lisp/org/ob-lilypond
/home/horn/.emacs.d/elpa/org-20141201/ob-org hides /home/horn/Repos/el/emacs/lisp/org/ob-org
/home/horn/.emacs.d/elpa/org-20141201/org-footnote hides /home/horn/Repos/el/emacs/lisp/org/org-footnote
~/Repos/el/gnus/lisp/dig hides /home/horn/Repos/el/emacs/lisp/net/dig
~/Repos/el/gnus/lisp/hmac-md5 hides /home/horn/Repos/el/emacs/lisp/net/hmac-md5
~/Repos/el/gnus/lisp/ntlm hides /home/horn/Repos/el/emacs/lisp/net/ntlm
~/Repos/el/gnus/lisp/hmac-def hides /home/horn/Repos/el/emacs/lisp/net/hmac-def
~/Repos/el/gnus/lisp/sasl-ntlm hides /home/horn/Repos/el/emacs/lisp/net/sasl-ntlm
~/Repos/el/gnus/lisp/sasl-cram hides /home/horn/Repos/el/emacs/lisp/net/sasl-cram
~/Repos/el/gnus/lisp/dns hides /home/horn/Repos/el/emacs/lisp/net/dns
~/Repos/el/gnus/lisp/sasl hides /home/horn/Repos/el/emacs/lisp/net/sasl
~/Repos/el/gnus/lisp/tls hides /home/horn/Repos/el/emacs/lisp/net/tls
~/Repos/el/gnus/lisp/netrc hides /home/horn/Repos/el/emacs/lisp/net/netrc
~/Repos/el/gnus/lisp/sasl-digest hides /home/horn/Repos/el/emacs/lisp/net/sasl-digest
~/Repos/el/gnus/lisp/uudecode hides /home/horn/Repos/el/emacs/lisp/mail/uudecode
~/Repos/el/gnus/lisp/binhex hides /home/horn/Repos/el/emacs/lisp/mail/binhex
~/Repos/el/gnus/lisp/hashcash hides /home/horn/Repos/el/emacs/lisp/mail/hashcash
~/Repos/el/gnus/lisp/canlock hides /home/horn/Repos/el/emacs/lisp/gnus/canlock
~/Repos/el/gnus/lisp/nneething hides /home/horn/Repos/el/emacs/lisp/gnus/nneething
~/Repos/el/gnus/lisp/mm-encode hides /home/horn/Repos/el/emacs/lisp/gnus/mm-encode
~/Repos/el/gnus/lisp/mm-util hides /home/horn/Repos/el/emacs/lisp/gnus/mm-util
~/Repos/el/gnus/lisp/rfc2047 hides /home/horn/Repos/el/emacs/lisp/gnus/rfc2047
~/Repos/el/gnus/lisp/nnml hides /home/horn/Repos/el/emacs/lisp/gnus/nnml
~/Repos/el/gnus/lisp/gnus-cus hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-cus
~/Repos/el/gnus/lisp/gnus-range hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-range
~/Repos/el/gnus/lisp/gnus-int hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-int
~/Repos/el/gnus/lisp/gnus-cloud hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-cloud
~/Repos/el/gnus/lisp/spam-stat hides /home/horn/Repos/el/emacs/lisp/gnus/spam-stat
~/Repos/el/gnus/lisp/nnmh hides /home/horn/Repos/el/emacs/lisp/gnus/nnmh
~/Repos/el/gnus/lisp/gnus-mlspl hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-mlspl
~/Repos/el/gnus/lisp/deuglify hides /home/horn/Repos/el/emacs/lisp/gnus/deuglify
~/Repos/el/gnus/lisp/gnus-gravatar hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-gravatar
~/Repos/el/gnus/lisp/nngateway hides /home/horn/Repos/el/emacs/lisp/gnus/nngateway
~/Repos/el/gnus/lisp/ietf-drums hides /home/horn/Repos/el/emacs/lisp/gnus/ietf-drums
~/Repos/el/gnus/lisp/mail-parse hides /home/horn/Repos/el/emacs/lisp/gnus/mail-parse
~/Repos/el/gnus/lisp/gnus-salt hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-salt
~/Repos/el/gnus/lisp/nnimap hides /home/horn/Repos/el/emacs/lisp/gnus/nnimap
~/Repos/el/gnus/lisp/gnus-draft hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-draft
~/Repos/el/gnus/lisp/mail-source hides /home/horn/Repos/el/emacs/lisp/gnus/mail-source
~/Repos/el/gnus/lisp/messcompat hides /home/horn/Repos/el/emacs/lisp/gnus/messcompat
~/Repos/el/gnus/lisp/pop3 hides /home/horn/Repos/el/emacs/lisp/gnus/pop3
~/Repos/el/gnus/lisp/nnmaildir hides /home/horn/Repos/el/emacs/lisp/gnus/nnmaildir
~/Repos/el/gnus/lisp/nnheader hides /home/horn/Repos/el/emacs/lisp/gnus/nnheader
~/Repos/el/gnus/lisp/gnus-cite hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-cite
~/Repos/el/gnus/lisp/rfc2104 hides /home/horn/Repos/el/emacs/lisp/gnus/rfc2104
~/Repos/el/gnus/lisp/nndiary hides /home/horn/Repos/el/emacs/lisp/gnus/nndiary
~/Repos/el/gnus/lisp/gnus-diary hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-diary
~/Repos/el/gnus/lisp/nnfolder hides /home/horn/Repos/el/emacs/lisp/gnus/nnfolder
~/Repos/el/gnus/lisp/gnus-art hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-art
~/Repos/el/gnus/lisp/gnus-demon hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-demon
~/Repos/el/gnus/lisp/mml-sec hides /home/horn/Repos/el/emacs/lisp/gnus/mml-sec
~/Repos/el/gnus/lisp/nnir hides /home/horn/Repos/el/emacs/lisp/gnus/nnir
~/Repos/el/gnus/lisp/mm-partial hides /home/horn/Repos/el/emacs/lisp/gnus/mm-partial
~/Repos/el/gnus/lisp/gnus-registry hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-registry
~/Repos/el/gnus/lisp/gnus-icalendar hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-icalendar
~/Repos/el/gnus/lisp/compface hides /home/horn/Repos/el/emacs/lisp/gnus/compface
~/Repos/el/gnus/lisp/gnus-fun hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-fun
~/Repos/el/gnus/lisp/gnus-start hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-start
~/Repos/el/gnus/lisp/smiley hides /home/horn/Repos/el/emacs/lisp/gnus/smiley
~/Repos/el/gnus/lisp/gnus-picon hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-picon
~/Repos/el/gnus/lisp/spam-report hides /home/horn/Repos/el/emacs/lisp/gnus/spam-report
~/Repos/el/gnus/lisp/nntp hides /home/horn/Repos/el/emacs/lisp/gnus/nntp
~/Repos/el/gnus/lisp/nnnil hides /home/horn/Repos/el/emacs/lisp/gnus/nnnil
~/Repos/el/gnus/lisp/nndir hides /home/horn/Repos/el/emacs/lisp/gnus/nndir
~/Repos/el/gnus/lisp/gnus-srvr hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-srvr
~/Repos/el/gnus/lisp/smime hides /home/horn/Repos/el/emacs/lisp/gnus/smime
~/Repos/el/gnus/lisp/nnvirtual hides /home/horn/Repos/el/emacs/lisp/gnus/nnvirtual
~/Repos/el/gnus/lisp/gnus-notifications hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-notifications
~/Repos/el/gnus/lisp/nnspool hides /home/horn/Repos/el/emacs/lisp/gnus/nnspool
~/Repos/el/gnus/lisp/gnus-group hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-group
~/Repos/el/gnus/lisp/gnus-bcklg hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-bcklg
~/Repos/el/gnus/lisp/gnus-util hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-util
~/Repos/el/gnus/lisp/gnus-sieve hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-sieve
~/Repos/el/gnus/lisp/nndraft hides /home/horn/Repos/el/emacs/lisp/gnus/nndraft
~/Repos/el/gnus/lisp/nnagent hides /home/horn/Repos/el/emacs/lisp/gnus/nnagent
~/Repos/el/gnus/lisp/gnus-spec hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-spec
~/Repos/el/gnus/lisp/gnus-bookmark hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-bookmark
~/Repos/el/gnus/lisp/mml1991 hides /home/horn/Repos/el/emacs/lisp/gnus/mml1991
~/Repos/el/gnus/lisp/rfc2231 hides /home/horn/Repos/el/emacs/lisp/gnus/rfc2231
~/Repos/el/gnus/lisp/yenc hides /home/horn/Repos/el/emacs/lisp/gnus/yenc
~/Repos/el/gnus/lisp/gnus-undo hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-undo
~/Repos/el/gnus/lisp/ecomplete hides /home/horn/Repos/el/emacs/lisp/gnus/ecomplete
~/Repos/el/gnus/lisp/legacy-gnus-agent hides /home/horn/Repos/el/emacs/lisp/gnus/legacy-gnus-agent
~/Repos/el/gnus/lisp/utf7 hides /home/horn/Repos/el/emacs/lisp/gnus/utf7
~/Repos/el/gnus/lisp/rtree hides /home/horn/Repos/el/emacs/lisp/gnus/rtree
~/Repos/el/gnus/lisp/gnus-uu hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-uu
~/Repos/el/gnus/lisp/gnus-ml hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-ml
~/Repos/el/gnus/lisp/sieve hides /home/horn/Repos/el/emacs/lisp/gnus/sieve
~/Repos/el/gnus/lisp/gnus hides /home/horn/Repos/el/emacs/lisp/gnus/gnus
~/Repos/el/gnus/lisp/mml hides /home/horn/Repos/el/emacs/lisp/gnus/mml
~/Repos/el/gnus/lisp/message hides /home/horn/Repos/el/emacs/lisp/gnus/message
~/Repos/el/gnus/lisp/mml-smime hides /home/horn/Repos/el/emacs/lisp/gnus/mml-smime
~/Repos/el/gnus/lisp/gnus-eform hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-eform
~/Repos/el/gnus/lisp/gnus-agent hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-agent
~/Repos/el/gnus/lisp/gnus-logic hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-logic
~/Repos/el/gnus/lisp/mm-extern hides /home/horn/Repos/el/emacs/lisp/gnus/mm-extern
~/Repos/el/gnus/lisp/nndoc hides /home/horn/Repos/el/emacs/lisp/gnus/nndoc
~/Repos/el/gnus/lisp/sieve-manage hides /home/horn/Repos/el/emacs/lisp/gnus/sieve-manage
~/Repos/el/gnus/lisp/mm-decode hides /home/horn/Repos/el/emacs/lisp/gnus/mm-decode
~/Repos/el/gnus/lisp/starttls hides /home/horn/Repos/el/emacs/lisp/gnus/starttls
~/Repos/el/gnus/lisp/gnus-dired hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-dired
~/Repos/el/gnus/lisp/nnbabyl hides /home/horn/Repos/el/emacs/lisp/gnus/nnbabyl
~/Repos/el/gnus/lisp/nnmbox hides /home/horn/Repos/el/emacs/lisp/gnus/nnmbox
~/Repos/el/gnus/lisp/gnus-win hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-win
~/Repos/el/gnus/lisp/gnus-async hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-async
~/Repos/el/gnus/lisp/mm-url hides /home/horn/Repos/el/emacs/lisp/gnus/mm-url
~/Repos/el/gnus/lisp/gnus-html hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-html
~/Repos/el/gnus/lisp/gssapi hides /home/horn/Repos/el/emacs/lisp/gnus/gssapi
~/Repos/el/gnus/lisp/mml2015 hides /home/horn/Repos/el/emacs/lisp/gnus/mml2015
~/Repos/el/gnus/lisp/nnrss hides /home/horn/Repos/el/emacs/lisp/gnus/nnrss
~/Repos/el/gnus/lisp/gnus-mh hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-mh
~/Repos/el/gnus/lisp/gnus-sum hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-sum
~/Repos/el/gnus/lisp/nnweb hides /home/horn/Repos/el/emacs/lisp/gnus/nnweb
~/Repos/el/gnus/lisp/mail-prsvr hides /home/horn/Repos/el/emacs/lisp/gnus/mail-prsvr
~/Repos/el/gnus/lisp/nnmairix hides /home/horn/Repos/el/emacs/lisp/gnus/nnmairix
~/Repos/el/gnus/lisp/plstore hides /home/horn/Repos/el/emacs/lisp/gnus/plstore
~/Repos/el/gnus/lisp/rfc2045 hides /home/horn/Repos/el/emacs/lisp/gnus/rfc2045
~/Repos/el/gnus/lisp/gnus-msg hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-msg
~/Repos/el/gnus/lisp/spam-wash hides /home/horn/Repos/el/emacs/lisp/gnus/spam-wash
~/Repos/el/gnus/lisp/gnus-score hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-score
~/Repos/el/gnus/lisp/mm-uu hides /home/horn/Repos/el/emacs/lisp/gnus/mm-uu
~/Repos/el/gnus/lisp/spam hides /home/horn/Repos/el/emacs/lisp/gnus/spam
~/Repos/el/gnus/lisp/mm-view hides /home/horn/Repos/el/emacs/lisp/gnus/mm-view
~/Repos/el/gnus/lisp/sieve-mode hides /home/horn/Repos/el/emacs/lisp/gnus/sieve-mode
~/Repos/el/gnus/lisp/html2text hides /home/horn/Repos/el/emacs/lisp/gnus/html2text
~/Repos/el/gnus/lisp/gnus-ems hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-ems
~/Repos/el/gnus/lisp/registry hides /home/horn/Repos/el/emacs/lisp/gnus/registry
~/Repos/el/gnus/lisp/auth-source hides /home/horn/Repos/el/emacs/lisp/gnus/auth-source
~/Repos/el/gnus/lisp/gravatar hides /home/horn/Repos/el/emacs/lisp/gnus/gravatar
~/Repos/el/gnus/lisp/flow-fill hides /home/horn/Repos/el/emacs/lisp/gnus/flow-fill
~/Repos/el/gnus/lisp/gmm-utils hides /home/horn/Repos/el/emacs/lisp/gnus/gmm-utils
~/Repos/el/gnus/lisp/mailcap hides /home/horn/Repos/el/emacs/lisp/gnus/mailcap
~/Repos/el/gnus/lisp/gnus-delay hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-delay
~/Repos/el/gnus/lisp/mm-bodies hides /home/horn/Repos/el/emacs/lisp/gnus/mm-bodies
~/Repos/el/gnus/lisp/mm-archive hides /home/horn/Repos/el/emacs/lisp/gnus/mm-archive
~/Repos/el/gnus/lisp/rfc1843 hides /home/horn/Repos/el/emacs/lisp/gnus/rfc1843
~/Repos/el/gnus/lisp/gnus-kill hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-kill
~/Repos/el/gnus/lisp/qp hides /home/horn/Repos/el/emacs/lisp/gnus/qp
~/Repos/el/gnus/lisp/score-mode hides /home/horn/Repos/el/emacs/lisp/gnus/score-mode
~/Repos/el/gnus/lisp/gnus-topic hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-topic
~/Repos/el/gnus/lisp/gnus-cache hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-cache
~/Repos/el/gnus/lisp/nnmail hides /home/horn/Repos/el/emacs/lisp/gnus/nnmail
~/Repos/el/gnus/lisp/gnus-vm hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-vm
~/Repos/el/gnus/lisp/gnus-sync hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-sync
~/Repos/el/gnus/lisp/nnoo hides /home/horn/Repos/el/emacs/lisp/gnus/nnoo
~/Repos/el/gnus/lisp/nnregistry hides /home/horn/Repos/el/emacs/lisp/gnus/nnregistry
~/Repos/el/gnus/lisp/gnus-dup hides /home/horn/Repos/el/emacs/lisp/gnus/gnus-dup
~/Repos/el/gnus/lisp/parse-time hides /home/horn/Repos/el/emacs/lisp/calendar/parse-time
~/Repos/el/gnus/lisp/time-date hides /home/horn/Repos/el/emacs/lisp/calendar/time-date

Features:
(rcirc-color rcirc-controls rcirc-late-fix rcirc eieio-opt speedbar
sb-image ezimage dframe misearch multi-isearch reftex-parse texmathp
vc-dispatcher vc-hg vc-git diff-mode cus-edit cus-start cus-load preview
prv-emacs auto-dictionary flyspell ispell tex-buf reftex-dcr reftex-auc
reftex reftex-vars font-latex latex tex-style tex dbus crm tex-mode
latexenc filecache ido hippie-exp shadow emacsbug sendmail shr-color
color shr dom subr-x pcase canlock gnus-fun gnus-dup qp url-http url-gw
url-auth sort smiley gnus-cite mm-archive gnus-async gnus-bcklg gnus-ml
hl-line nndraft nnmh rot13 utf-7 gnutls network-stream nsm starttls nnml
nnnil gnus-agent gnus-srvr gnus-score score-mode nnvirtual gnus-cache
gnus-demon nntp spam spam-stat gnus-uu yenc gnus-msg gnus-gravatar
mail-extr gravatar gnus-topic nnir gnus-registry registry eieio-base
th-private bs company-files company-oddmuse company-keywords
company-etags company-gtags company-dabbrev-code company-dabbrev
company-capf company-cmake company-ropemacs company-xcode company-clang
company-semantic company-eclim company-template company-css company-nxml
company-bbdb highlight-parentheses company stratego-mode greql-mode
tg-mode generic preview-latex tex-site auto-loads cider tramp-sh
cider-mode cider-repl cider-eldoc cider-interaction apropos arc-mode
archive-mode cider-doc org-table ox-reveal ox-latex ox-icalendar ox-html
ox-ascii ox-publish ox org-element org org-macro org-footnote
org-pcomplete org-list org-faces org-entities org-version ob-emacs-lisp
ob ob-tangle ob-ref ob-lob ob-table ob-exp org-src ob-keys ob-comint
ob-core ob-eval org-compat org-macs org-loaddefs cal-menu calendar
cal-loaddefs cider-test cider-stacktrace cider-client nrepl-client queue
cider-util ewoc etags clojure-mode imenu paredit aggressive-indent names
edebug epa-file epa epg rdictcc google-contacts-message google-contacts
derived url-cache google-oauth google-contacts-gnus gnus-art mm-uu
mml2015 mm-view mml-smime smime dig gnus-sum gnus-group gnus-undo
gnus-start gnus-cloud nnimap nnmail mail-source tls utf7 netrc nnoo
parse-time gnus-spec gnus-int gnus-range gnus-win gnus gnus-ems
gnus-compat nnheader em-term term ehelp esh-opt esh-ext esh-util
highlight-symbol boxquote rect ecomplete message rfc822 mml mml-sec
mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045
ietf-drums mailabbrev mail-utils gmm-utils mailheader edit-server server
yasnippet help-mode disp-table noutline outline browse-kill-ring recentf
tree-widget wid-edit helm-projectile helm-files image-dired tramp
tramp-compat tramp-loaddefs trampver shell pcomplete format-spec dired-x
dired-aux ffap helm-tags helm-bookmark helm-adaptive helm-info helm-net
browse-url xml url url-proxy url-privacy url-expand url-methods
url-history url-cookie url-domsuf url-util url-parse auth-source
gnus-util mm-util mail-prsvr password-cache url-vars mailcap bookmark pp
helm-help helm-match-plugin helm-external helm-buffers helm-grep
helm-regexp helm-plugin helm-elscreen helm-utils dired helm-locate helm
helm-source eieio byte-opt bytecomp byte-compile cl-extra cconv
eieio-core helm-config async-bytecomp async helm-aliases projectile
ibuf-ext ibuffer pkg-info find-func lisp-mnt epl grep compile comint
ansi-color ring f s ucs-normalize thingatpt easy-mmode cl-macs iedit
help-macro iedit-lib cl gv cap-words superword subword saveplace
savehist paren icomplete mb-depth smart-mode-line-respectful-theme
smart-mode-line-light-theme rich-minority smart-mode-line mule-util dash
rx edmacro kmacro cl-loaddefs cl-lib elec-pair gnus-load
tsdh-light-theme memory-usage-autoloads advice help-fns info easymenu
package epg-config time-date tooltip eldoc electric uniquify ediff-hook
vc-hooks lisp-float-type mwheel x-win x-dnd tool-bar dnd fontset image
regexp-opt fringe tabulated-list newcomment elisp-mode lisp-mode
prog-mode register page menu-bar rfn-eshadow timer select scroll-bar
mouse jit-lock font-lock syntax facemenu font-core frame cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese case-table epa-hook jka-cmpr-hook help simple abbrev
minibuffer nadvice loaddefs button faces cus-face macroexp files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote make-network-process
dbusbind gfilenotify dynamic-setting system-font-setting
font-render-setting move-toolbar gtk x-toolkit x multi-tty emacs)

Memory information:
((conses 16 1042508 108386)
 (symbols 48 63249 2)
 (miscs 40 476 1106)
 (strings 32 194666 21683)
 (string-bytes 1 6360662)
 (vectors 16 87053)
 (vector-slots 8 2265089 181909)
 (floats 8 728 720)
 (intervals 56 12336 2392)
 (buffers 976 61)
 (heap 1024 111979 12030))





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2014-12-04  8:06 bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted Tassilo Horn
@ 2022-05-12  2:16 ` Lars Ingebrigtsen
  2022-05-12  4:53   ` Tassilo Horn
  2022-05-12  5:40   ` Eli Zaretskii
  0 siblings, 2 replies; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-12  2:16 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: 19267

Tassilo Horn <tsdh@gnu.org> writes:

> I like the new `cycle-spacing' command but I frequently would like to
> have an additional space where only the whitespace after point is
> deleted.  That'd be useful when manually formatting text (code) where
> auto-indentation isn't available.  My prime use-case is laying out
> example code snippets in comments and docstrings which I copied & pasted
> from somewhere else.  E.g., I start with a docstring
>
>   "Example:
>
>      (let [x :something]
>        |                  (foo x)
>                           (bar x))"
>
> where | is the position of point.  In that case, I'd like if M-SPC would
> change the text to
>
>   "Example:
>
>      (let [x :something]
>        |(foo x)
>                           (bar x))"
>
> instead of
>
>   "Example:
>
>      (let [x :something]
>  |(foo x)
>                           (bar x))"
>
> i.e., it first M-SPC only deletes whitespace after point but not before.
> I don't really care if that's the first state (although that would be
> plausible, i.e., states are cycled from more space to less spaces), but
> at least it should be a reachable state.

(I'm going through old bug reports that unfortunately weren't resolved
at the time.)

I think that sounds like a good feature -- we don't have any other
commands for "delete all whitespace after point", do we?

We could implement this as a new third state for `cycle-spacing', and
move the "restore" to the fourth state.  Does anybody think that will be
annoying for people?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12  2:16 ` Lars Ingebrigtsen
@ 2022-05-12  4:53   ` Tassilo Horn
  2022-05-12 11:45     ` Lars Ingebrigtsen
  2022-05-12  5:40   ` Eli Zaretskii
  1 sibling, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-12  4:53 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 19267

Lars Ingebrigtsen <larsi@gnus.org> writes:

Hi Lars,

>> I like the new `cycle-spacing' command but I frequently would like to
>> have an additional space where only the whitespace after point is
>> deleted.  That'd be useful when manually formatting text (code) where
>> auto-indentation isn't available.  My prime use-case is laying out
>> example code snippets in comments and docstrings which I copied &
>> pasted from somewhere else.  E.g., I start with a docstring
>>
>>   "Example:
>>
>>      (let [x :something]
>>        |                  (foo x)
>>                           (bar x))"
>>
>> where | is the position of point.  In that case, I'd like if M-SPC
>> would change the text to
>>
>>   "Example:
>>
>>      (let [x :something]
>>        |(foo x)
>>                           (bar x))"
>>
>> instead of
>>
>>   "Example:
>>
>>      (let [x :something]
>>  |(foo x)
>>                           (bar x))"
>>
>> i.e., it first M-SPC only deletes whitespace after point but not before.
>> I don't really care if that's the first state (although that would be
>> plausible, i.e., states are cycled from more space to less spaces), but
>> at least it should be a reachable state.
>
> (I'm going through old bug reports that unfortunately weren't resolved
> at the time.)
>
> I think that sounds like a good feature -- we don't have any other
> commands for "delete all whitespace after point", do we?

No, just the opposite: delete-horizontal-space with prefix arg.

> We could implement this as a new third state for `cycle-spacing', and
> move the "restore" to the fourth state.  Does anybody think that will
> be annoying for people?

It makes the sequence longer in case you want to restore.  Not a big
thing IMHO.  But maybe there could also be a new defcustom
cycle-spacing-actions which lists the actions being cycled, e.g.,

  (just-one-space delete-all-space delete-space-after restore-original)

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12  2:16 ` Lars Ingebrigtsen
  2022-05-12  4:53   ` Tassilo Horn
@ 2022-05-12  5:40   ` Eli Zaretskii
  2022-05-12  5:46     ` Tassilo Horn
  2022-05-12  8:25     ` Robert Pluim
  1 sibling, 2 replies; 40+ messages in thread
From: Eli Zaretskii @ 2022-05-12  5:40 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 19267, tsdh

> Cc: 19267@debbugs.gnu.org
> From: Lars Ingebrigtsen <larsi@gnus.org>
> Date: Thu, 12 May 2022 04:16:06 +0200
> 
> > i.e., it first M-SPC only deletes whitespace after point but not before.
> > I don't really care if that's the first state (although that would be
> > plausible, i.e., states are cycled from more space to less spaces), but
> > at least it should be a reachable state.
> 
> (I'm going through old bug reports that unfortunately weren't resolved
> at the time.)
> 
> I think that sounds like a good feature -- we don't have any other
> commands for "delete all whitespace after point", do we?
> 
> We could implement this as a new third state for `cycle-spacing', and
> move the "restore" to the fourth state.  Does anybody think that will be
> annoying for people?

Is cycle-spacing bound to some key sequence in some modes?  If so, we
should ask users of those modes, because as long as cycle-spacing can
only be invoked via M-x, I don't believe another state would matter
much.





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12  5:40   ` Eli Zaretskii
@ 2022-05-12  5:46     ` Tassilo Horn
  2022-05-12  8:25     ` Robert Pluim
  1 sibling, 0 replies; 40+ messages in thread
From: Tassilo Horn @ 2022-05-12  5:46 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Lars Ingebrigtsen, 19267

Eli Zaretskii <eliz@gnu.org> writes:

>> We could implement this as a new third state for `cycle-spacing', and
>> move the "restore" to the fourth state.  Does anybody think that will
>> be annoying for people?
>
> Is cycle-spacing bound to some key sequence in some modes?  If so, we
> should ask users of those modes, because as long as cycle-spacing can
> only be invoked via M-x, I don't believe another state would matter
> much.

I think cycle-spacing is basically a more elaborate version of
just-one-space so I expect many users have a remapping from
just-one-space to cycle-spacing as I do.  I think that has been part of
the discussion back then and it's suggested in that way in NEWS.24:

--8<---------------cut here---------------start------------->8---
** New command `cycle-spacing' acts like a smarter `just-one-space'.
When called in succession, it cycles between spacing conventions:
one space, no spaces, original spacing.
--8<---------------cut here---------------end--------------->8---

On a related note: I think next to the suggested "delete only spaces
after point", the same with "before point" could also make sense in
certain situations...

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12  5:40   ` Eli Zaretskii
  2022-05-12  5:46     ` Tassilo Horn
@ 2022-05-12  8:25     ` Robert Pluim
  2022-05-12  8:29       ` Eli Zaretskii
  1 sibling, 1 reply; 40+ messages in thread
From: Robert Pluim @ 2022-05-12  8:25 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Lars Ingebrigtsen, 19267, tsdh

>>>>> On Thu, 12 May 2022 08:40:53 +0300, Eli Zaretskii <eliz@gnu.org> said:

    >> Cc: 19267@debbugs.gnu.org
    >> From: Lars Ingebrigtsen <larsi@gnus.org>
    >> Date: Thu, 12 May 2022 04:16:06 +0200
    >> 
    >> > i.e., it first M-SPC only deletes whitespace after point but not before.
    >> > I don't really care if that's the first state (although that would be
    >> > plausible, i.e., states are cycled from more space to less spaces), but
    >> > at least it should be a reachable state.
    >> 
    >> (I'm going through old bug reports that unfortunately weren't resolved
    >> at the time.)
    >> 
    >> I think that sounds like a good feature -- we don't have any other
    >> commands for "delete all whitespace after point", do we?
    >> 
    >> We could implement this as a new third state for `cycle-spacing', and
    >> move the "restore" to the fourth state.  Does anybody think that will be
    >> annoying for people?

    Eli> Is cycle-spacing bound to some key sequence in some modes?  If so, we
    Eli> should ask users of those modes, because as long as cycle-spacing can
    Eli> only be invoked via M-x, I don't believe another state would matter
    Eli> much.

Not as far as I can tell. Having tried it, Iʼd even be tempted to make
`cycle-spacing' be the default for M-SPC (itʼs only been around for a
decade or so, how did I never know about it?)

Robert
-- 





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12  8:25     ` Robert Pluim
@ 2022-05-12  8:29       ` Eli Zaretskii
  0 siblings, 0 replies; 40+ messages in thread
From: Eli Zaretskii @ 2022-05-12  8:29 UTC (permalink / raw)
  To: Robert Pluim; +Cc: larsi, 19267, tsdh

> From: Robert Pluim <rpluim@gmail.com>
> Cc: Lars Ingebrigtsen <larsi@gnus.org>,  19267@debbugs.gnu.org,  tsdh@gnu.org
> Date: Thu, 12 May 2022 10:25:03 +0200
> 
> Having tried it, Iʼd even be tempted to make `cycle-spacing' be the
> default for M-SPC (itʼs only been around for a decade or so, how did
> I never know about it?)

That's because it has a non-nil 'not-during-the-first-decade'
property.





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12  4:53   ` Tassilo Horn
@ 2022-05-12 11:45     ` Lars Ingebrigtsen
  2022-05-12 11:56       ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-12 11:45 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: 19267

Tassilo Horn <tsdh@gnu.org> writes:

>> I think that sounds like a good feature -- we don't have any other
>> commands for "delete all whitespace after point", do we?
>
> No, just the opposite: delete-horizontal-space with prefix arg.

Huh, I'd forgotten about that one.  It's pretty odd to have both `C-\'
and `M-SPC' bound when both commands are so similar.

I guess people have different usage patterns -- for instance, I only use
`M-- M-SPC' (`just-one-space' that also deletes newlines), because
that's what's usually useful in Lisp code.

>> We could implement this as a new third state for `cycle-spacing', and
>> move the "restore" to the fourth state.  Does anybody think that will
>> be annoying for people?
>
> It makes the sequence longer in case you want to restore.  Not a big
> thing IMHO.  But maybe there could also be a new defcustom
> cycle-spacing-actions which lists the actions being cycled, e.g.,
>
>   (just-one-space delete-all-space delete-space-after restore-original)

Hm, yes, that might be good.  If the list of cycled actions gets to
long, it's no longer convenient.  So for myself, I'd probably have

(just-one-space-including-newlines delete-after-space restore-original)

and then `M-SPC' would do what I wanted in 99% of the time (with my
usage patterns).  (We could also add target actions like `no-space' and
`no-space-before-point' (i.e., the `M-\' actions).)

So perhaps we could change the `M-SPC' binding to a new
`cycle-spacing-command' that, by default, does exactly what
`just-one-space' does now (so that there will be no user visible
changes; i.e., it doesn't cycle because cycle-spacing-actions will be
just (just-one-space)).  But then users can customize it and add the
actions they want in a convenient way.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12 11:45     ` Lars Ingebrigtsen
@ 2022-05-12 11:56       ` Tassilo Horn
  2022-05-12 12:09         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-12 11:56 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 19267

Hi Lars,

> Hm, yes, that might be good.  If the list of cycled actions gets to
> long, it's no longer convenient.  So for myself, I'd probably have
>
> (just-one-space-including-newlines delete-after-space restore-original)
>
> and then `M-SPC' would do what I wanted in 99% of the time (with my
> usage patterns).  (We could also add target actions like `no-space'
> and `no-space-before-point' (i.e., the `M-\' actions).)
>
> So perhaps we could change the `M-SPC' binding to a new
> `cycle-spacing-command' that, by default, does exactly what
> `just-one-space' does now (so that there will be no user visible
> changes; i.e., it doesn't cycle because cycle-spacing-actions will be
> just (just-one-space)).  But then users can customize it and add the
> actions they want in a convenient way.

Ah, compatibility questions...

I'd say just create a cycle-spacing-actions defcustom and use that in
the existing cycle-spacing instead of the hard-coded sequence.  And bind
M-SPC to cycle-spacing by default because it's simply superior (a
super-set) of just-one-space.

I mean, how would people discover the possibility of customizing
cycle-spacing-actions if not by checking the info docs and/or NEWS
(where cycle-spacing is already mentioned as a more powerful
just-one-space alternative)?  And nobody would look in there if the
default behavior is just-one-space.  We need a disruptive change! :-)

But that's just me.

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12 11:56       ` Tassilo Horn
@ 2022-05-12 12:09         ` Lars Ingebrigtsen
  2022-05-12 12:16           ` Robert Pluim
  2022-05-12 12:20           ` Tassilo Horn
  0 siblings, 2 replies; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-12 12:09 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: 19267

Tassilo Horn <tsdh@gnu.org> writes:

> I'd say just create a cycle-spacing-actions defcustom and use that in
> the existing cycle-spacing instead of the hard-coded sequence.  And bind
> M-SPC to cycle-spacing by default because it's simply superior (a
> super-set) of just-one-space.

It's two actions, and one which can't be done via Customize...

> I mean, how would people discover the possibility of customizing
> cycle-spacing-actions if not by checking the info docs and/or NEWS
> (where cycle-spacing is already mentioned as a more powerful
> just-one-space alternative)?  And nobody would look in there if the
> default behavior is just-one-space.  We need a disruptive change! :-)

If we do this change, they'll find out about the variable by doing
`C-h M-SPC'.  Eventually.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12 12:09         ` Lars Ingebrigtsen
@ 2022-05-12 12:16           ` Robert Pluim
  2022-05-12 12:21             ` Lars Ingebrigtsen
  2022-05-12 12:20           ` Tassilo Horn
  1 sibling, 1 reply; 40+ messages in thread
From: Robert Pluim @ 2022-05-12 12:16 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 19267, Tassilo Horn

>>>>> On Thu, 12 May 2022 14:09:23 +0200, Lars Ingebrigtsen <larsi@gnus.org> said:

    Lars> Tassilo Horn <tsdh@gnu.org> writes:
    >> I'd say just create a cycle-spacing-actions defcustom and use that in
    >> the existing cycle-spacing instead of the hard-coded sequence.  And bind
    >> M-SPC to cycle-spacing by default because it's simply superior (a
    >> super-set) of just-one-space.

    Lars> It's two actions, and one which can't be done via Customize...

Which is why we should change the default binding of M-SPC to
cycle-spacing. I know some people will complain, but all they have to
do is not type M-SPC twice. In short: Iʼm with Tassilo, letʼs be
disruptive.

Robert
-- 





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12 12:09         ` Lars Ingebrigtsen
  2022-05-12 12:16           ` Robert Pluim
@ 2022-05-12 12:20           ` Tassilo Horn
  1 sibling, 0 replies; 40+ messages in thread
From: Tassilo Horn @ 2022-05-12 12:20 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 19267

Lars Ingebrigtsen <larsi@gnus.org> writes:

>> I'd say just create a cycle-spacing-actions defcustom and use that in
>> the existing cycle-spacing instead of the hard-coded sequence.  And
>> bind M-SPC to cycle-spacing by default because it's simply superior
>> (a super-set) of just-one-space.
>
> It's two actions, and one which can't be done via Customize...

I don't understand.  What can't be done via Customize?  Users who want
back the old behavior could customize cycle-spacing-actions to
(just-one-space) and have the same behavior as if M-SPC was still bound
to just-one-space, no?  Or they can re-bind M-SPC back to just-one-space
(ok, that can't be done via customize).

>> I mean, how would people discover the possibility of customizing
>> cycle-spacing-actions if not by checking the info docs and/or NEWS
>> (where cycle-spacing is already mentioned as a more powerful
>> just-one-space alternative)?  And nobody would look in there if the
>> default behavior is just-one-space.  We need a disruptive change! :-)
>
> If we do this change, they'll find out about the variable by doing
> `C-h M-SPC'.  Eventually.

Yeah, eventually maybe.  My point is that if the behavior doesn't
change, most people won't check.  I mean, I don't `C-h k' bindings I
think I know.  I do that when I don't get what I expected where the
actual behavior may very well be better than what I expected.

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12 12:16           ` Robert Pluim
@ 2022-05-12 12:21             ` Lars Ingebrigtsen
  2022-05-12 14:45               ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-12 12:21 UTC (permalink / raw)
  To: Robert Pluim; +Cc: 19267, Tassilo Horn

Robert Pluim <rpluim@gmail.com> writes:

> Which is why we should change the default binding of M-SPC to
> cycle-spacing. I know some people will complain, but all they have to
> do is not type M-SPC twice. In short: Iʼm with Tassilo, letʼs be
> disruptive.

Thinking about it a bit more, I agree with you two.  It'd be minimally
disruptive, anyway -- nobody is likely to have a work flow that depends
on hitting `M-SPC' many times in a row, because a second invocation of
`just-one-space' does nothing.

So I think we should rebind `M-SPC' to `cycle-spacing', and allow
customizations of the cycles.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12 12:21             ` Lars Ingebrigtsen
@ 2022-05-12 14:45               ` Tassilo Horn
  2022-05-13  8:50                 ` Tassilo Horn
  2022-05-13 12:19                 ` Lars Ingebrigtsen
  0 siblings, 2 replies; 40+ messages in thread
From: Tassilo Horn @ 2022-05-12 14:45 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

Lars Ingebrigtsen <larsi@gnus.org> writes:

Hi Lars,

>> Which is why we should change the default binding of M-SPC to
>> cycle-spacing. I know some people will complain, but all they have to
>> do is not type M-SPC twice. In short: Iʼm with Tassilo, letʼs be
>> disruptive.
>
> Thinking about it a bit more, I agree with you two.

I'll print that statement and put it in a frame in my living room. ;-)

> It'd be minimally disruptive, anyway -- nobody is likely to have a
> work flow that depends on hitting `M-SPC' many times in a row, because
> a second invocation of `just-one-space' does nothing.

Oh, indeed!

> So I think we should rebind `M-SPC' to `cycle-spacing', and allow
> customizations of the cycles.

Perfect.  If you are not already implementing that, I'd give it a shot
when I find some spare time.

BTW, do we already have a function which given an element and a
(conceptually cyclic) list returns the element after that.  E.g., such
as this one:

--8<---------------cut here---------------start------------->8---
(defun th/seq-element-after (elt list)
  (let ((l list))
    (catch 'found
      (while l
        (cond
         ((null (cdr l))
          (throw 'found
                 (when (eq elt (car l))
                   (car list))))
         ((and (eq elt (car l))
               (cdr l))
          (throw 'found (cadr l)))
         (t (setq l (cdr l))))))))

(setq th/test-list '(a b c))
(th/seq-element-after 'a th/test-list) ;=> b
(th/seq-element-after 'b th/test-list) ;=> c
(th/seq-element-after 'c th/test-list) ;=> a
(th/seq-element-after 'x th/test-list) ;=> nil
--8<---------------cut here---------------end--------------->8---

We need such a helper for the functionality.  The question is just if
it's generally useful in which case I'd ask for a good name and place
(accessible from simple.el).  Otherwise, I'd just keep it as an
anonymous helper...

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12 14:45               ` Tassilo Horn
@ 2022-05-13  8:50                 ` Tassilo Horn
  2022-05-13 13:33                   ` Robert Pluim
  2022-05-13 12:19                 ` Lars Ingebrigtsen
  1 sibling, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-13  8:50 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

[-- Attachment #1: Type: text/plain, Size: 3044 bytes --]

Tassilo Horn <tsdh@gnu.org> writes:

Hi all,

> Perfect.  If you are not already implementing that, I'd give it a shot
> when I find some spare time.

Ok, attached is a first version of the patch for discussion.  The
supported actions are:

(setq cycle-spacing-actions
      '( just-one-space        ; you name it
         ;; delete-space-after ; delete spaces after point
         delete-space-before   ; delete spaces before point
         delete-all-space      ; delete all spaces around point
         restore))             ; restore the original spacing

In addition, you can add functions (symbols) into that list which are
simply funcall-ed.

Here are some thoughts I'd like to discuss:

1. Currently as previously, changing the prefix arg will start a new
   sequence, e.g., M-4 M-SPC M-8 M-SPC will call just-one-space twice
   with 4 and then 8.  I think that made sense when just-one-space was
   guaranteed to be the first action ("Oh, I mistyped my prefix arg so
   let's just correct that!").

   However, with the new version, I think it would make more sense when
   the prefix arg given to the initial invocation is passed on to
   following invocations of this cycle.  The reason is that only
   just-one-space actually cares about the exact numerical value whereas
   all actions (except 'restore) care about the prefix arg being
   positive or negative.  A negative arg always indicates that newlines
   are treated as a deletable space whereas arg => 0 only considers tabs
   and spaces.  So right now, if you want to delete all space including
   newlines, you have to type M-- M-SPC M-- M-SPC M-- M-SPC which is
   inconvenient.  If the initial arg was passed on, it would just be M--
   M-SPC M-SPC M-SPC which is much easier to type.

   Of course, that comes with the (IMHO little) downside that you need
   to do something else to break a cycle, e.g., C-g.  That could be
   fixed by starting a new cycle only if the prefix arg is not 1 (the
   default).

2. With my configured emacs (but not with emacs -Q) it may take a
   substantial amount of time (up to a second) until the action's effect
   is displayed, most notably when cycling with negative prefix arg
   where also newlines may be deleted.  Profiling revealed that this
   comes mostly through stuff sitting in post-command-hook or
   after-change-functions.  To name a few: aggressive-indent, show-paren
   (which I use with the costly show-paren-context-when-offscreen
   value 'child-frame), eldoc,...

   Ok, aggressive-indent is countering manual spacing adjustments
   fundamentally but can be tamed with:

       (add-to-list 'aggressive-indent-dont-indent-if
                    '(eq last-command 'cycle-spacing))

   But is there some good way to tame the others?  It's hard to decide
   which known performance hogs to inhibit and there might be much worse
   unknown ones.  (Well, I also don't know how to inhibit.  I guess
   let-binding post-command-hook in a command has no effect since it's
   run after the command, right?)

Bye,
Tassilo


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-cycle-spacing.patch --]
[-- Type: text/x-patch, Size: 9245 bytes --]

From c2b5bea92a39f094dbc2cbd07a51feed4d588639 Mon Sep 17 00:00:00 2001
From: Tassilo Horn <tsdh@gnu.org>
Date: Thu, 12 May 2022 23:24:47 +0200
Subject: [PATCH] Improve cycle-spacing

---
 lisp/bindings.el |   2 +-
 lisp/simple.el   | 165 +++++++++++++++++++++++++++++++++++------------
 2 files changed, 124 insertions(+), 43 deletions(-)

diff --git a/lisp/bindings.el b/lisp/bindings.el
index bfe5ba8623..ed1325e326 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -990,7 +990,7 @@ esc-map
 (define-key esc-map "\\" 'delete-horizontal-space)
 (define-key esc-map "m" 'back-to-indentation)
 (define-key ctl-x-map "\C-o" 'delete-blank-lines)
-(define-key esc-map " " 'just-one-space)
+(define-key esc-map " " 'cycle-spacing)
 (define-key esc-map "z" 'zap-to-char)
 (define-key esc-map "=" 'count-words-region)
 (define-key ctl-x-map "=" 'what-cursor-position)
diff --git a/lisp/simple.el b/lisp/simple.el
index 3812f6d8c6..e0f64e3566 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1072,15 +1072,24 @@ delete-horizontal-space
   "Delete all spaces and tabs around point.
 If BACKWARD-ONLY is non-nil, delete them only before point."
   (interactive "*P")
+  (delete-space--internal " \t" backward-only))
+
+(defun delete-all-space (&optional backward-only)
+  "Delete all spaces, tabs, and newlines around point.
+If BACKWARD-ONLY is non-nil, delete them only before point."
+  (interactive "*P")
+  (delete-space--internal " \t\r\n" backward-only))
+
+(defun delete-space--internal (chars backward-only)
   (let ((orig-pos (point)))
     (delete-region
      (if backward-only
-	 orig-pos
+         orig-pos
        (progn
-	 (skip-chars-forward " \t")
-	 (constrain-to-field nil orig-pos t)))
+         (skip-chars-forward chars)
+         (constrain-to-field nil orig-pos t)))
      (progn
-       (skip-chars-backward " \t")
+       (skip-chars-backward chars)
        (constrain-to-field nil orig-pos)))))
 
 (defun just-one-space (&optional n)
@@ -1088,15 +1097,43 @@ just-one-space
 If N is negative, delete newlines as well, leaving -N spaces.
 See also `cycle-spacing'."
   (interactive "*p")
-  (cycle-spacing n nil 'single-shot))
+  (let ((orig-pos        (point))
+        (skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
+        (num             (abs (or n 1))))
+    (skip-chars-backward skip-characters)
+    (constrain-to-field nil orig-pos)
+    (let* ((num   (- num (skip-chars-forward " " (+ num (point)))))
+           (mid   (point))
+           (end   (progn
+                    (skip-chars-forward skip-characters)
+                    (constrain-to-field nil orig-pos t))))
+      (delete-region mid end)
+      (insert (make-string num ?\s)))))
 
 (defvar cycle-spacing--context nil
+  ;; TODO: Adapt docstring!
   "Store context used in consecutive calls to `cycle-spacing' command.
 The first time `cycle-spacing' runs, it saves in this variable:
 its N argument, the original point position, and the original spacing
 around point.")
 
-(defun cycle-spacing (&optional n preserve-nl-back mode)
+(setq cycle-spacing-actions
+      '( just-one-space
+         ;; delete-space-after ; pretty similar to just-one-space.
+         delete-space-before
+         delete-all-space
+         restore))
+
+(defun cycle-spacing (&optional n)
+  ;; TODO: Adapt docstring!
+
+  ;; TODO: We removed the preserve-nl-back and mode args since they
+  ;; were not used in emacs anyway except by just-one-space
+  ;; (single-shot) which now has its own impl and cycle-spacing calls
+  ;; it.  What about the `fast' mode value which used to immediately
+  ;; perform the second step if the first didn't change anything?
+  ;; IMO, that made sense only when just-one-space was guaranteed to
+  ;; be the first and "delete all horizontal space" the second...
   "Manipulate whitespace around point in a smart way.
 In interactive use, this function behaves differently in successive
 consecutive calls.
@@ -1119,42 +1156,86 @@ cycle-spacing
 Repeatedly calling the function with different values of N starts a
 new sequence each time."
   (interactive "*p")
-  (let ((orig-pos	 (point))
-	(skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
-	(num		 (abs (or n 1))))
-    (skip-chars-backward (if preserve-nl-back " \t" skip-characters))
-    (constrain-to-field nil orig-pos)
-    (cond
-     ;; Command run for the first time, single-shot mode or different argument
-     ((or (eq 'single-shot mode)
-	  (not (equal last-command this-command))
-	  (not cycle-spacing--context)
-	  (not (eq (car cycle-spacing--context) n)))
-      (let* ((start (point))
-	     (num   (- num (skip-chars-forward " " (+ num (point)))))
-	     (mid   (point))
-	     (end   (progn
-		      (skip-chars-forward skip-characters)
-		      (constrain-to-field nil orig-pos t))))
-	(setq cycle-spacing--context  ;; Save for later.
-	      ;; Special handling for case where there was no space at all.
-	      (unless (= start end)
-                (cons n (cons orig-pos (buffer-substring start (point))))))
-	;; If this run causes no change in buffer content, delete all spaces,
-	;; otherwise delete all excess spaces.
-	(delete-region (if (and (eq mode 'fast) (zerop num) (= mid end))
-			   start mid) end)
-        (insert (make-string num ?\s))))
-
-     ;; Command run for the second time.
-     ((not (equal orig-pos (point)))
-      (delete-region (point) orig-pos))
-
-     ;; Command run for the third time.
-     (t
-      (insert (cddr cycle-spacing--context))
-      (goto-char (cadr cycle-spacing--context))
-      (setq cycle-spacing--context nil)))))
+
+  ;; Initialize `cycle-spacing--context' if needed.
+  (when (or (not (equal last-command this-command))
+            (not cycle-spacing--context)
+            (not (= (plist-get cycle-spacing--context :n) n)))
+    (let ((orig-pos	 (point))
+          (skip-characters " \t\n\r"))
+      (save-excursion
+        (skip-chars-backward skip-characters)
+        (constrain-to-field nil orig-pos)
+        (let ((start (point))
+              (end   (progn
+                       (skip-chars-forward skip-characters)
+                       (constrain-to-field nil orig-pos t))))
+          (setq cycle-spacing--context  ;; Save for later.
+                ;; Special handling for case where there was no space at all.
+                (unless (= start end)
+                  (list :orig-pos orig-pos
+                        :whitespace-string (buffer-substring start end)
+                        :n n
+                        :last-action nil)))))))
+
+  ;; Cycle through the actions in `cycle-spacing-actions'.
+  (when cycle-spacing--context
+    (cl-flet ((next-action ()
+                (let* ((l cycle-spacing-actions)
+                       (elt (plist-get cycle-spacing--context
+                                       :last-action)))
+                  (if (null elt)
+                      (car cycle-spacing-actions)
+                    (catch 'found
+                      (while l
+                        (cond
+                         ((null (cdr l))
+                          (throw 'found
+                                 (when (eq elt (car l))
+                                   (car cycle-spacing-actions))))
+                         ((and (eq elt (car l))
+                               (cdr l))
+                          (throw 'found (cadr l)))
+                         (t (setq l (cdr l)))))))))
+              (restore (kill-context)
+                (delete-all-space)
+                (insert (plist-get cycle-spacing--context
+                                   :whitespace-string))
+                (goto-char (plist-get cycle-spacing--context
+                                      :orig-pos))
+                (when kill-context
+                  (setq cycle-spacing--context nil))))
+      (let ((action (next-action)))
+        (atomic-change-group
+          (if (eq action 'restore)
+              (restore t)
+            (restore nil)
+            (let ((n (plist-get cycle-spacing--context :n)))
+              (cond
+               ((eq action 'just-one-space)
+                (just-one-space n))
+               ((eq action 'delete-space-after)
+                (delete-region (point)
+                               (progn
+                                 (skip-chars-forward
+                                  (if (< n 0) " \t\r\n" " \t"))
+                                 (point))))
+               ((eq action 'delete-space-before)
+                (delete-region (point)
+                               (progn
+                                 (skip-chars-backward
+                                  (if (< n 0) " \t\r\n" " \t"))
+                                 (point))))
+               ((eq action 'delete-all-space)
+                (if (< n 0)
+                    (delete-all-space)
+                  (delete-horizontal-space)))
+               ((functionp action)
+                (funcall action))
+               (t
+                (error "Don't know how to handle action %S" action))))
+            (setf (plist-get cycle-spacing--context :last-action)
+                  action)))))))
 \f
 (defun beginning-of-buffer (&optional arg)
   "Move point to the beginning of the buffer.
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-12 14:45               ` Tassilo Horn
  2022-05-13  8:50                 ` Tassilo Horn
@ 2022-05-13 12:19                 ` Lars Ingebrigtsen
  2022-05-13 13:36                   ` Robert Pluim
  2022-05-13 19:01                   ` Tassilo Horn
  1 sibling, 2 replies; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-13 12:19 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Robert Pluim, 19267

Tassilo Horn <tsdh@gnu.org> writes:

>> Thinking about it a bit more, I agree with you two.
>
> I'll print that statement and put it in a frame in my living room. ;-)

:-)

> BTW, do we already have a function which given an element and a
> (conceptually cyclic) list returns the element after that.  E.g., such
> as this one:

Isn't that basically just (cadr (last list (mod i (length list)))) or
something like that?  (There's probably at least five off-by-ones in
that form.  😀  And...  you'd need a special test for the first element.)

> We need such a helper for the functionality.  The question is just if
> it's generally useful in which case I'd ask for a good name and place
> (accessible from simple.el).  Otherwise, I'd just keep it as an
> anonymous helper...

Sure, I think that sounds like a nice function.

Tassilo Horn <tsdh@gnu.org> writes:

> Ok, attached is a first version of the patch for discussion.  The
> supported actions are:
>
> (setq cycle-spacing-actions
>       '( just-one-space        ; you name it
>          ;; delete-space-after ; delete spaces after point
>          delete-space-before   ; delete spaces before point
>          delete-all-space      ; delete all spaces around point
>          restore))             ; restore the original spacing
>
> In addition, you can add functions (symbols) into that list which are
> simply funcall-ed.

Sounds good.  There should also be a just-one-space-including-newlines
(which is the `M-- M-SPC' action), and...  Uhm, perhaps that's all
that's missing, if we want to cover all the `M-SPC'/`M-\' actions.

Or perhaps newline-including versions of all the functions, really.

>    However, with the new version, I think it would make more sense when
>    the prefix arg given to the initial invocation is passed on to
>    following invocations of this cycle.  The reason is that only
>    just-one-space actually cares about the exact numerical value whereas
>    all actions (except 'restore) care about the prefix arg being
>    positive or negative.

delete-space-before/after could also care about the numerical prefix?

>    A negative arg always indicates that newlines
>    are treated as a deletable space whereas arg => 0 only considers tabs
>    and spaces.  So right now, if you want to delete all space including
>    newlines, you have to type M-- M-SPC M-- M-SPC M-- M-SPC which is
>    inconvenient.  If the initial arg was passed on, it would just be M--
>    M-SPC M-SPC M-SPC which is much easier to type.

After typing `M-- M-SPC' once, further incantations of that doesn't do
anything, does it?

> 2. With my configured emacs (but not with emacs -Q) it may take a
>    substantial amount of time (up to a second) until the action's effect
>    is displayed, most notably when cycling with negative prefix arg
>    where also newlines may be deleted.  Profiling revealed that this
>    comes mostly through stuff sitting in post-command-hook or
>    after-change-functions.  To name a few: aggressive-indent, show-paren
>    (which I use with the costly show-paren-context-when-offscreen
>    value 'child-frame), eldoc,...
>
>    Ok, aggressive-indent is countering manual spacing adjustments
>    fundamentally but can be tamed with:
>
>        (add-to-list 'aggressive-indent-dont-indent-if
>                     '(eq last-command 'cycle-spacing))
>
>    But is there some good way to tame the others?  It's hard to decide
>    which known performance hogs to inhibit and there might be much worse
>    unknown ones.  (Well, I also don't know how to inhibit.  I guess
>    let-binding post-command-hook in a command has no effect since it's
>    run after the command, right?)

I don't think this command should do anything about these hooks.  If the
user has put oddball stuff into the hooks, that's up to them.  (The
action is instantaneous for me.)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-13  8:50                 ` Tassilo Horn
@ 2022-05-13 13:33                   ` Robert Pluim
  2022-05-13 18:48                     ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Robert Pluim @ 2022-05-13 13:33 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Lars Ingebrigtsen, 19267

>>>>> On Fri, 13 May 2022 10:50:22 +0200, Tassilo Horn <tsdh@gnu.org> said:

    Tassilo> Tassilo Horn <tsdh@gnu.org> writes:
    Tassilo> Hi all,

    >> Perfect.  If you are not already implementing that, I'd give it a shot
    >> when I find some spare time.

    Tassilo> Ok, attached is a first version of the patch for discussion.  The
    Tassilo> supported actions are:

    Tassilo> (setq cycle-spacing-actions
    Tassilo>       '( just-one-space        ; you name it
    Tassilo>          ;; delete-space-after ; delete spaces after point
    Tassilo>          delete-space-before   ; delete spaces before point
    Tassilo>          delete-all-space      ; delete all spaces around point
    Tassilo>          restore))             ; restore the original spacing

Can we add something to the description of `delete-all-space' (or
change the name) that makes it clear it deletes newlines as well?

    Tassilo> In addition, you can add functions (symbols) into that list which are
    Tassilo> simply funcall-ed.

    Tassilo> Here are some thoughts I'd like to discuss:

    Tassilo> 1. Currently as previously, changing the prefix arg will start a new
    Tassilo>    sequence, e.g., M-4 M-SPC M-8 M-SPC will call just-one-space twice
    Tassilo>    with 4 and then 8.  I think that made sense when just-one-space was
    Tassilo>    guaranteed to be the first action ("Oh, I mistyped my prefix arg so
    Tassilo>    let's just correct that!").

    Tassilo>    However, with the new version, I think it would make more sense when
    Tassilo>    the prefix arg given to the initial invocation is passed on to
    Tassilo>    following invocations of this cycle.  The reason is that only
    Tassilo>    just-one-space actually cares about the exact numerical value whereas
    Tassilo>    all actions (except 'restore) care about the prefix arg being
    Tassilo>    positive or negative.  A negative arg always indicates that newlines
    Tassilo>    are treated as a deletable space whereas arg => 0 only considers tabs
    Tassilo>    and spaces.  So right now, if you want to delete all space including
    Tassilo>    newlines, you have to type M-- M-SPC M-- M-SPC M-- M-SPC which is
    Tassilo>    inconvenient.  If the initial arg was passed on, it would just be M--
    Tassilo>    M-SPC M-SPC M-SPC which is much easier to type.

I think that makes sense. You can always specify a prefix arg of a
different sign in subsequent invocations of M-SPC if you want.

    Tassilo>    Of course, that comes with the (IMHO little) downside that you need
    Tassilo>    to do something else to break a cycle, e.g., C-g.  That could be
    Tassilo>    fixed by starting a new cycle only if the prefix arg is not 1 (the
    Tassilo>    default).

Would a motion command not suffice?

    Tassilo> 2. With my configured emacs (but not with emacs -Q) it may take a
    Tassilo>    substantial amount of time (up to a second) until the action's effect
    Tassilo>    is displayed, most notably when cycling with negative prefix arg
    Tassilo>    where also newlines may be deleted.  Profiling revealed that this
    Tassilo>    comes mostly through stuff sitting in post-command-hook or
    Tassilo>    after-change-functions.  To name a few: aggressive-indent, show-paren
    Tassilo>    (which I use with the costly show-paren-context-when-offscreen
    Tassilo>    value 'child-frame), eldoc,...

    Tassilo>    Ok, aggressive-indent is countering manual spacing adjustments
    Tassilo>    fundamentally but can be tamed with:

    Tassilo>        (add-to-list 'aggressive-indent-dont-indent-if
    Tassilo>                     '(eq last-command 'cycle-spacing))

    Tassilo>    But is there some good way to tame the others?  It's hard to decide
    Tassilo>    which known performance hogs to inhibit and there might be much worse
    Tassilo>    unknown ones.  (Well, I also don't know how to inhibit.  I guess
    Tassilo>    let-binding post-command-hook in a command has no effect since it's
    Tassilo>    run after the command, right?)

I think we should worry about any performance side-effects once we run
into them.

Robert
-- 





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-13 12:19                 ` Lars Ingebrigtsen
@ 2022-05-13 13:36                   ` Robert Pluim
  2022-05-13 13:39                     ` Lars Ingebrigtsen
  2022-05-13 19:01                   ` Tassilo Horn
  1 sibling, 1 reply; 40+ messages in thread
From: Robert Pluim @ 2022-05-13 13:36 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 19267, Tassilo Horn

>>>>> On Fri, 13 May 2022 14:19:47 +0200, Lars Ingebrigtsen <larsi@gnus.org> said:

    Lars> Tassilo Horn <tsdh@gnu.org> writes:
    >>> Thinking about it a bit more, I agree with you two.
    >> 
    >> I'll print that statement and put it in a frame in my living room. ;-)

    Lars> :-)

    >> BTW, do we already have a function which given an element and a
    >> (conceptually cyclic) list returns the element after that.  E.g., such
    >> as this one:

    Lars> Isn't that basically just (cadr (last list (mod i (length list)))) or
    Lars> something like that?  (There's probably at least five off-by-ones in
    Lars> that form.  😀  And...  you'd need a special test for the first element.)

ring.el?

Robert
-- 





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-13 13:36                   ` Robert Pluim
@ 2022-05-13 13:39                     ` Lars Ingebrigtsen
  0 siblings, 0 replies; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-13 13:39 UTC (permalink / raw)
  To: Robert Pluim; +Cc: 19267, Tassilo Horn

Robert Pluim <rpluim@gmail.com> writes:

> ring.el?

It doesn't really do lists, does it?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-13 13:33                   ` Robert Pluim
@ 2022-05-13 18:48                     ` Tassilo Horn
  0 siblings, 0 replies; 40+ messages in thread
From: Tassilo Horn @ 2022-05-13 18:48 UTC (permalink / raw)
  To: Robert Pluim; +Cc: Lars Ingebrigtsen, 19267

Robert Pluim <rpluim@gmail.com> writes:

>     Tassilo> Ok, attached is a first version of the patch for
>     Tassilo> discussion.  The supported actions are:
>
>     Tassilo> (setq cycle-spacing-actions
>     Tassilo>       '( just-one-space        ; you name it
>     Tassilo>          ;; delete-space-after ; delete spaces after point
>     Tassilo>          delete-space-before   ; delete spaces before point
>     Tassilo>          delete-all-space      ; delete all spaces around point
>     Tassilo>          restore))             ; restore the original spacing
>
> Can we add something to the description of `delete-all-space' (or
> change the name) that makes it clear it deletes newlines as well?

It doesn't generally.  All those actions delete newlines only if a
negative prefix arg is given.  The delete-all-space action calls
delete-horizontal-space with prefix arg >= 0 or delete-all-space with
negative prefix arg.

Ok, now I see that the action's name is the same as the command
delete-all-space which I've also introduced and which does delete
newlines.  But an action delete-horizontal-or-all-space is a bit
longish.  I think it's ok as it is but will document that the term
"space" may or may not include newlines.

>     Tassilo> In addition, you can add functions (symbols) into that list which are
>     Tassilo> simply funcall-ed.
>
>     Tassilo> Here are some thoughts I'd like to discuss:
>
>     Tassilo> 1. Currently as previously, changing the prefix arg will start a new
>     Tassilo>    sequence, e.g., M-4 M-SPC M-8 M-SPC will call just-one-space twice
>     Tassilo>    with 4 and then 8.  I think that made sense when just-one-space was
>     Tassilo>    guaranteed to be the first action ("Oh, I mistyped my prefix arg so
>     Tassilo>    let's just correct that!").
>
>     Tassilo>    However, with the new version, I think it would make more sense when
>     Tassilo>    the prefix arg given to the initial invocation is passed on to
>     Tassilo>    following invocations of this cycle.  The reason is that only
>     Tassilo>    just-one-space actually cares about the exact numerical value whereas
>     Tassilo>    all actions (except 'restore) care about the prefix arg being
>     Tassilo>    positive or negative.  A negative arg always indicates that newlines
>     Tassilo>    are treated as a deletable space whereas arg => 0 only considers tabs
>     Tassilo>    and spaces.  So right now, if you want to delete all space including
>     Tassilo>    newlines, you have to type M-- M-SPC M-- M-SPC M-- M-SPC which is
>     Tassilo>    inconvenient.  If the initial arg was passed on, it would just be M--
>     Tassilo>    M-SPC M-SPC M-SPC which is much easier to type.
>
> I think that makes sense. You can always specify a prefix arg of a
> different sign in subsequent invocations of M-SPC if you want.

Exactly.

>     Tassilo>    Of course, that comes with the (IMHO little) downside that you need
>     Tassilo>    to do something else to break a cycle, e.g., C-g.  That could be
>     Tassilo>    fixed by starting a new cycle only if the prefix arg is not 1 (the
>     Tassilo>    default).
>
> Would a motion command not suffice?

Sure.  But after a mistyped M-3 M-SPC with the intention to have "just 4
spaces", being able to do M-4 M-SPC is still one motion command
shorter. ;-)

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-13 12:19                 ` Lars Ingebrigtsen
  2022-05-13 13:36                   ` Robert Pluim
@ 2022-05-13 19:01                   ` Tassilo Horn
  2022-05-13 19:26                     ` Lars Ingebrigtsen
  1 sibling, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-13 19:01 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

Lars Ingebrigtsen <larsi@gnus.org> writes:

>> Ok, attached is a first version of the patch for discussion.  The
>> supported actions are:
>>
>> (setq cycle-spacing-actions
>>       '( just-one-space        ; you name it
>>          ;; delete-space-after ; delete spaces after point
>>          delete-space-before   ; delete spaces before point
>>          delete-all-space      ; delete all spaces around point
>>          restore))             ; restore the original spacing
>>
>> In addition, you can add functions (symbols) into that list which are
>> simply funcall-ed.
>
> Sounds good.  There should also be a just-one-space-including-newlines
> (which is the `M-- M-SPC' action), and...  Uhm, perhaps that's all
> that's missing, if we want to cover all the `M-SPC'/`M-\' actions.
>
> Or perhaps newline-including versions of all the functions, really.

I'll make it so that the prefix arg is passed on in the cycle so M--
M-SPC M-SPC will delete all space including newline before point.  IMO,
that's better than a separate action.

>>    However, with the new version, I think it would make more sense
>>    when the prefix arg given to the initial invocation is passed on
>>    to following invocations of this cycle.  The reason is that only
>>    just-one-space actually cares about the exact numerical value
>>    whereas all actions (except 'restore) care about the prefix arg
>>    being positive or negative.
>
> delete-space-before/after could also care about the numerical prefix?

Yes, in the sense that negative means "including newlines".

>>    A negative arg always indicates that newlines are treated as a
>>    deletable space whereas arg => 0 only considers tabs and spaces.
>>    So right now, if you want to delete all space including newlines,
>>    you have to type M-- M-SPC M-- M-SPC M-- M-SPC which is
>>    inconvenient.  If the initial arg was passed on, it would just be
>>    M-- M-SPC M-SPC M-SPC which is much easier to type.
>
> After typing `M-- M-SPC' once, further incantations of that doesn't do
> anything, does it?

Right now and with my patch, M-- M-SPC would call (just-one-space -1)
and the next M-SPC would start another cycle with (just-one-space 1)
because the prefix arg changed.

My suggestion is that M-- M-SPC M-SPC will call (just-one-space -1)
(delete-space-before -1) [ok, the latter is no function but you get the
idea].

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-13 19:01                   ` Tassilo Horn
@ 2022-05-13 19:26                     ` Lars Ingebrigtsen
  2022-05-13 21:11                       ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-13 19:26 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Robert Pluim, 19267

Tassilo Horn <tsdh@gnu.org> writes:

> I'll make it so that the prefix arg is passed on in the cycle so M--
> M-SPC M-SPC will delete all space including newline before point.  IMO,
> that's better than a separate action.

I want a separate action, because the current `M-- M-SPC' action is
basically the only one I use, and I want to be able to just type `M-SPC'
to get it.

>> delete-space-before/after could also care about the numerical prefix?
>
> Yes, in the sense that negative means "including newlines".

I meant in the same way just-one-space does.  I.e., leave 4 space after
point if given a 4 prefix, etc.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-13 19:26                     ` Lars Ingebrigtsen
@ 2022-05-13 21:11                       ` Tassilo Horn
  2022-05-14  2:24                         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-13 21:11 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

[-- Attachment #1: Type: text/plain, Size: 1141 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

>> I'll make it so that the prefix arg is passed on in the cycle so M--
>> M-SPC M-SPC will delete all space including newline before point.
>> IMO, that's better than a separate action.
>
> I want a separate action, because the current `M-- M-SPC' action is
> basically the only one I use, and I want to be able to just type
> `M-SPC' to get it.

Would it be ok for you to define it in your init file?  I've documented
the positive arg = tabs/spaces, negative arg = tabs/spaces/newlines as a
general contract of all predefined actions (see new patch below) and
your favorite action would immediately violate it...

>>> delete-space-before/after could also care about the numerical
>>> prefix?
>>
>> Yes, in the sense that negative means "including newlines".
>
> I meant in the same way just-one-space does.  I.e., leave 4 space after
> point if given a 4 prefix, etc.

No, at least not yet. But if they did, you would need to always give an
explicit prefix arg when you really want to delete all spaces
before/after point because the default value of a numerical prefix arg
is 1.

Bye,
Tassilo


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-cycle-spacing.patch --]
[-- Type: text/x-patch, Size: 14664 bytes --]

From 1550ec47094667158292122bc7bb0114d0c48cbd Mon Sep 17 00:00:00 2001
From: Tassilo Horn <tsdh@gnu.org>
Date: Thu, 12 May 2022 23:24:47 +0200
Subject: [PATCH] Improve cycle-spacing

---
 doc/emacs/killing.texi |  25 +++--
 etc/NEWS               |   5 +
 lisp/bindings.el       |   2 +-
 lisp/simple.el         | 230 +++++++++++++++++++++++++++++------------
 4 files changed, 184 insertions(+), 78 deletions(-)

diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 2fd2d21dd3..30025134eb 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -111,24 +111,27 @@ Deletion
 
 @kindex M-\
 @findex delete-horizontal-space
-@kindex M-SPC
-@findex just-one-space
-@findex cycle-spacing
-  The other delete commands are those that delete only whitespace
+The other delete commands are those that delete only whitespace
 characters: spaces, tabs and newlines.  @kbd{M-\}
 (@code{delete-horizontal-space}) deletes all the spaces and tab
 characters before and after point.  With a prefix argument, this only
-deletes spaces and tab characters before point.  @kbd{M-@key{SPC}}
-(@code{just-one-space}) does likewise but leaves a single space before
+deletes spaces and tab characters before point.
+
+@findex just-one-space
+@code{just-one-space} does likewise but leaves a single space before
 point, regardless of the number of spaces that existed previously
 (even if there were none before).  With a numeric argument @var{n}, it
 leaves @var{n} spaces before point if @var{n} is positive; if @var{n}
 is negative, it deletes newlines in addition to spaces and tabs,
-leaving @minus{}@var{n} spaces before point.  The command @code{cycle-spacing}
-acts like a more flexible version of @code{just-one-space}.  It
-does different things if you call it repeatedly in succession.
-The first call acts like @code{just-one-space}, the next removes
-all whitespace, and a third call restores the original whitespace.
+leaving @minus{}@var{n} spaces before point.
+
+@kindex M-SPC
+@findex cycle-spacing
+@vindex cycle-spacing-actions
+The command @code{cycle-spacing} (@kbd{M-@key{SPC}}) acts like a more
+flexible version of @code{just-one-space}.  It performs different
+space cleanup actions if you call it repeatedly in succession as
+defined by @code{cycle-spacing-actions}.
 
   @kbd{C-x C-o} (@code{delete-blank-lines}) deletes all blank lines
 after the current line.  If the current line is blank, it deletes all
diff --git a/etc/NEWS b/etc/NEWS
index d93a79ed36..2e7c408607 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -672,6 +672,11 @@ recreate it anew next time 'imenu' is invoked.
 
 * Editing Changes in Emacs 29.1
 
++++
+** M-SPC is now bound to 'cycle-spacing' (formerly it was 'just-one-space').
+The actions performed by 'cycle-spacing' and their order can now be
+customized via 'cycle-spacing-actions'.
+
 ---
 ** 'scroll-other-window' and 'scroll-other-window-down' now respects remapping.
 These commands (bound to 'C-M-v' and 'C-M-V') used to scroll the other
diff --git a/lisp/bindings.el b/lisp/bindings.el
index bfe5ba8623..ed1325e326 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -990,7 +990,7 @@ esc-map
 (define-key esc-map "\\" 'delete-horizontal-space)
 (define-key esc-map "m" 'back-to-indentation)
 (define-key ctl-x-map "\C-o" 'delete-blank-lines)
-(define-key esc-map " " 'just-one-space)
+(define-key esc-map " " 'cycle-spacing)
 (define-key esc-map "z" 'zap-to-char)
 (define-key esc-map "=" 'count-words-region)
 (define-key ctl-x-map "=" 'what-cursor-position)
diff --git a/lisp/simple.el b/lisp/simple.el
index 3812f6d8c6..325b1bb506 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1072,15 +1072,24 @@ delete-horizontal-space
   "Delete all spaces and tabs around point.
 If BACKWARD-ONLY is non-nil, delete them only before point."
   (interactive "*P")
+  (delete-space--internal " \t" backward-only))
+
+(defun delete-all-space (&optional backward-only)
+  "Delete all spaces, tabs, and newlines around point.
+If BACKWARD-ONLY is non-nil, delete them only before point."
+  (interactive "*P")
+  (delete-space--internal " \t\r\n" backward-only))
+
+(defun delete-space--internal (chars backward-only)
   (let ((orig-pos (point)))
     (delete-region
      (if backward-only
-	 orig-pos
+         orig-pos
        (progn
-	 (skip-chars-forward " \t")
-	 (constrain-to-field nil orig-pos t)))
+         (skip-chars-forward chars)
+         (constrain-to-field nil orig-pos t)))
      (progn
-       (skip-chars-backward " \t")
+       (skip-chars-backward chars)
        (constrain-to-field nil orig-pos)))))
 
 (defun just-one-space (&optional n)
@@ -1088,73 +1097,162 @@ just-one-space
 If N is negative, delete newlines as well, leaving -N spaces.
 See also `cycle-spacing'."
   (interactive "*p")
-  (cycle-spacing n nil 'single-shot))
+  (let ((orig-pos        (point))
+        (skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
+        (num             (abs (or n 1))))
+    (skip-chars-backward skip-characters)
+    (constrain-to-field nil orig-pos)
+    (let* ((num   (- num (skip-chars-forward " " (+ num (point)))))
+           (mid   (point))
+           (end   (progn
+                    (skip-chars-forward skip-characters)
+                    (constrain-to-field nil orig-pos t))))
+      (delete-region mid end)
+      (insert (make-string num ?\s)))))
 
 (defvar cycle-spacing--context nil
-  "Store context used in consecutive calls to `cycle-spacing' command.
-The first time `cycle-spacing' runs, it saves in this variable:
-its N argument, the original point position, and the original spacing
-around point.")
+  "Stored context used in consecutive calls to `cycle-spacing' command.
+The value is a property list with the following elements:
+- `:orig-pos'    The original position of point when starting the
+                 sequence.
+- `:whitespace-string' All whitespace characters around point
+                       including newlines.
+- `:n'            The prefix arg given to the initial invocation
+                  which is reused for all actions in this cycle.
+- `:last-action'  The last action performed in the cycle.")
+
+(defcustom cycle-spacing-actions
+  '( just-one-space
+     delete-space-after
+     delete-space-before
+     delete-all-space
+     restore)
+  "List of actions cycled through by `cycle-spacing'.
+Supported values are:
+- `just-one-space'      Delete all but N (prefix arg) spaces.
+                        See that command's docstring for details.
+- `delete-space-after'  Delete spaces after point.
+- `delete-space-before' Delete spaces before point.
+- `delete-all-space'    Delete all spaces around point.
+- `restore'             Restore the original spacing.
+
+All those predefined actions make use of the numeric prefix arg
+given to `cycle-spacing', i.e., `just-one-space' keeps this
+amount of spaces deleting surplus ones.  `just-one-space' and all
+other actions have the contract that a positive prefix arg (or
+zero) only deletes tabs and spaces whereas a negative prefix arg
+also deletes newlines.
+
+In addition, any function which accepts one numeric argument is
+allowed."
+  :group 'editing-basics
+  :type '(repeat
+          (choice
+           (const :tag "Just N (prefix arg) spaces" just-one-space)
+           (const :tag "Delete spaces after point" delete-space-after)
+           (const :tag "Delete spaces before point" delete-space-before)
+           (const :tag "Delete all spaces around point" delete-all-space)
+           (const :tag "Restore the original spacing" restore)
+           (function :tag "Function receiving a numerig arg")))
+  :version "29.1")
 
-(defun cycle-spacing (&optional n preserve-nl-back mode)
+(defun cycle-spacing (&optional n)
   "Manipulate whitespace around point in a smart way.
-In interactive use, this function behaves differently in successive
-consecutive calls.
-
-The first call in a sequence acts like `just-one-space'.
-It deletes all spaces and tabs around point, leaving one space
-\(or N spaces).  N is the prefix argument.  If N is negative,
-it deletes newlines as well, leaving -N spaces.
-\(If PRESERVE-NL-BACK is non-nil, it does not delete newlines before point.)
-
-The second call in a sequence deletes all spaces.
-
-The third call in a sequence restores the original whitespace (and point).
-
-If MODE is `single-shot', it performs only the first step in the sequence.
-If MODE is `fast' and the first step would not result in any change
-\(i.e., there are exactly (abs N) spaces around point),
-the function goes straight to the second step.
-
-Repeatedly calling the function with different values of N starts a
-new sequence each time."
+Repeated calls perform the actions in `cycle-spacing-actions' one
+after the other, wrapping around after the last one.
+
+All actions are amendable using a prefix arg N.  In general, a
+zero or positive prefix arg allows only for deletion of tabs and
+spaces whereas a negative prefix arg also allows for deleting
+newlines.
+
+The prefix arg given at the first invocation starting a cycle is
+provided to all following actions, i.e.,
+    \\[negative-argument] \\[cycle-spacing] \\[cycle-spacing] \\[cycle-spacing]
+is equivalent to
+    \\[negative-argument] \\[cycle-spacing] \\[negative-argument] \\[cycle-spacing] \\[negative-argument] \\[cycle-spacing].
+
+A new sequence can be started by providing a different prefix arg
+than provided at the initial invocation (except for 1), or by
+doing any other command before the next \\[cycle-spacing]."
   (interactive "*p")
-  (let ((orig-pos	 (point))
-	(skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
-	(num		 (abs (or n 1))))
-    (skip-chars-backward (if preserve-nl-back " \t" skip-characters))
-    (constrain-to-field nil orig-pos)
-    (cond
-     ;; Command run for the first time, single-shot mode or different argument
-     ((or (eq 'single-shot mode)
-	  (not (equal last-command this-command))
-	  (not cycle-spacing--context)
-	  (not (eq (car cycle-spacing--context) n)))
-      (let* ((start (point))
-	     (num   (- num (skip-chars-forward " " (+ num (point)))))
-	     (mid   (point))
-	     (end   (progn
-		      (skip-chars-forward skip-characters)
-		      (constrain-to-field nil orig-pos t))))
-	(setq cycle-spacing--context  ;; Save for later.
-	      ;; Special handling for case where there was no space at all.
-	      (unless (= start end)
-                (cons n (cons orig-pos (buffer-substring start (point))))))
-	;; If this run causes no change in buffer content, delete all spaces,
-	;; otherwise delete all excess spaces.
-	(delete-region (if (and (eq mode 'fast) (zerop num) (= mid end))
-			   start mid) end)
-        (insert (make-string num ?\s))))
-
-     ;; Command run for the second time.
-     ((not (equal orig-pos (point)))
-      (delete-region (point) orig-pos))
-
-     ;; Command run for the third time.
-     (t
-      (insert (cddr cycle-spacing--context))
-      (goto-char (cadr cycle-spacing--context))
-      (setq cycle-spacing--context nil)))))
+  ;; Initialize `cycle-spacing--context' if needed.
+  (when (or (not (equal last-command this-command))
+            (not cycle-spacing--context)
+            ;; With M-5 M-SPC M-SPC... we pass the prefix arg 5 to
+            ;; each action and only start a new cycle when a different
+            ;; prefix arg is given and which is not the default value
+            ;; 1.
+            (and (not (= n 1))
+                 (not (= (plist-get cycle-spacing--context :n) n))))
+    (let ((orig-pos (point))
+          (skip-characters " \t\n\r"))
+      (save-excursion
+        (skip-chars-backward skip-characters)
+        (constrain-to-field nil orig-pos)
+        (let ((start (point))
+              (end   (progn
+                       (skip-chars-forward skip-characters)
+                       (constrain-to-field nil orig-pos t))))
+          (setq cycle-spacing--context  ;; Save for later.
+                (list :orig-pos orig-pos
+                      :whitespace-string (buffer-substring start end)
+                      :n n
+                      :last-action nil))))))
+
+  ;; Cycle through the actions in `cycle-spacing-actions'.
+  (when cycle-spacing--context
+    (cl-flet ((next-action ()
+                (let* ((l cycle-spacing-actions)
+                       (elt (plist-get cycle-spacing--context
+                                       :last-action)))
+                  (if (null elt)
+                      (car cycle-spacing-actions)
+                    (catch 'found
+                      (while l
+                        (cond
+                         ((null (cdr l))
+                          (throw 'found
+                                 (when (eq elt (car l))
+                                   (car cycle-spacing-actions))))
+                         ((and (eq elt (car l))
+                               (cdr l))
+                          (throw 'found (cadr l)))
+                         (t (setq l (cdr l)))))))))
+              (restore ()
+                (delete-all-space)
+                (insert (plist-get cycle-spacing--context
+                                   :whitespace-string))
+                (goto-char (plist-get cycle-spacing--context
+                                      :orig-pos))))
+      (let ((action (next-action)))
+        (atomic-change-group
+          (restore)
+          (unless (eq action 'restore)
+            (let ((context-n (plist-get cycle-spacing--context :n)))
+              (cond
+               ((eq action 'just-one-space)
+                (just-one-space context-n))
+               ((eq action 'delete-space-after)
+                (delete-region (point)
+                               (progn
+                                 (skip-chars-forward
+                                  (if (< context-n 0) " \t\r\n" " \t"))
+                                 (constrain-to-field nil (point) t))))
+               ((eq action 'delete-space-before)
+                (if (< context-n 0)
+                    (delete-all-space t)
+                  (delete-horizontal-space t)))
+               ((eq action 'delete-all-space)
+                (if (< context-n 0)
+                    (delete-all-space)
+                  (delete-horizontal-space)))
+               ((functionp action)
+                (funcall action context-n))
+               (t
+                (error "Don't know how to handle action %S" action)))))
+          (setf (plist-get cycle-spacing--context :last-action)
+                action))))))
 \f
 (defun beginning-of-buffer (&optional arg)
   "Move point to the beginning of the buffer.
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-13 21:11                       ` Tassilo Horn
@ 2022-05-14  2:24                         ` Lars Ingebrigtsen
  2022-05-14  6:54                           ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-14  2:24 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Robert Pluim, 19267

Tassilo Horn <tsdh@gnu.org> writes:

> Would it be ok for you to define it in your init file?  I've documented
> the positive arg = tabs/spaces, negative arg = tabs/spaces/newlines as a
> general contract of all predefined actions (see new patch below) and
> your favorite action would immediately violate it...

I think the newline-including variations would be as popular as the
non-newline ones, so I think we should have those variations for all of
the actions.

Perhaps `M--' could work as a toggle -- if the action doesn't include
newlines, `M--' switches on, and if it does, `M--' switches it off.

> No, at least not yet. But if they did, you would need to always give an
> explicit prefix arg when you really want to delete all spaces
> before/after point because the default value of a numerical prefix arg
> is 1.

But it doesn't have to be, surely?  No prefix for
delete-space-after-point could mean exactly that, but a prefix of four
could mean leave four.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-14  2:24                         ` Lars Ingebrigtsen
@ 2022-05-14  6:54                           ` Tassilo Horn
  2022-05-14 15:51                             ` Lars Ingebrigtsen
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-14  6:54 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

Lars Ingebrigtsen <larsi@gnus.org> writes:

Hi Lars,

>> Would it be ok for you to define it in your init file?  I've documented
>> the positive arg = tabs/spaces, negative arg = tabs/spaces/newlines as a
>> general contract of all predefined actions (see new patch below) and
>> your favorite action would immediately violate it...
>
> I think the newline-including variations would be as popular as the
> non-newline ones, so I think we should have those variations for all
> of the actions.

You're quite strong willed, aren't you? ;-)

> Perhaps `M--' could work as a toggle -- if the action doesn't include
> newlines, `M--' switches on, and if it does, `M--' switches it off.

That's indeed an idea.  How about cycle-spacing-actions could also have
actions of the form

    (just-one-space inverted-arg)
    (just-one-space 4)

where the former would, you guess it, use the inverted value of this
cycle's prefix arg and the latter would ignore the cycle's prefix arg
and just use 4?  That would fit your desire, right?

>> No, at least not yet. But if they did, you would need to always give
>> an explicit prefix arg when you really want to delete all spaces
>> before/after point because the default value of a numerical prefix
>> arg is 1.
>
> But it doesn't have to be, surely?  No prefix for
> delete-space-after-point could mean exactly that, but a prefix of four
> could mean leave four.

I don't like that no prefix arg (aka 1) would be treated differently
than any other value.  And what if you actually want to delete all but
one space?

Or do you suggest that cycle-spacing should be changed from taking a
numeric prefix arg to a raw prefix arg and then do the conversion to
numeric itself (with prefix-numeric-value)?  That would make it possible
to distinguish no prefix arg from 1.  I think that would be benefitical
otherwise, e.g., to force a new cycle.

In any case, how would you define the semantics for the delete-* actions
with numeric values for N?  I mean, for delete-space-after/before I can
imagine that the N whitespace characters after/before should survive (in
case there are at least so many).  But in case of delete-all-space,
there's no precise meaning of the correct spaces around point which
could be a wild mix of spaces, tabs, and newlines.

I'd rather suggest to leave the delete-* actions as-is and add another
just-one-newline (and probably also just-one-newline-and-indent) action
which is like just-one-space with newline instead of space (plus one
indent-according-to-mode).

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-14  6:54                           ` Tassilo Horn
@ 2022-05-14 15:51                             ` Lars Ingebrigtsen
  2022-05-15  9:02                               ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-14 15:51 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Robert Pluim, 19267

Tassilo Horn <tsdh@gnu.org> writes:

> That's indeed an idea.  How about cycle-spacing-actions could also have
> actions of the form
>
>     (just-one-space inverted-arg)
>     (just-one-space 4)
>
> where the former would, you guess it, use the inverted value of this
> cycle's prefix arg and the latter would ignore the cycle's prefix arg
> and just use 4?  That would fit your desire, right?

Sure, makes sense.  `inverted-arg' could be `-', even.

> Or do you suggest that cycle-spacing should be changed from taking a
> numeric prefix arg to a raw prefix arg and then do the conversion to
> numeric itself (with prefix-numeric-value)?

Yes.

> In any case, how would you define the semantics for the delete-* actions
> with numeric values for N?  I mean, for delete-space-after/before I can
> imagine that the N whitespace characters after/before should survive (in
> case there are at least so many).  But in case of delete-all-space,
> there's no precise meaning of the correct spaces around point which
> could be a wild mix of spaces, tabs, and newlines.

It's not meaningful for delete-all-space, but that's OK.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-14 15:51                             ` Lars Ingebrigtsen
@ 2022-05-15  9:02                               ` Tassilo Horn
  2022-05-15 12:27                                 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-15  9:02 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

[-- Attachment #1: Type: text/plain, Size: 1941 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

Hi Lars,

>> That's indeed an idea.  How about cycle-spacing-actions could also
>> have actions of the form
>>
>>     (just-one-space inverted-arg)
>>     (just-one-space 4)
>>
>> where the former would, you guess it, use the inverted value of this
>> cycle's prefix arg and the latter would ignore the cycle's prefix arg
>> and just use 4?  That would fit your desire, right?
>
> Sure, makes sense.  `inverted-arg' could be `-', even.

Ok, done, see attached patch.

>> Or do you suggest that cycle-spacing should be changed from taking a
>> numeric prefix arg to a raw prefix arg and then do the conversion to
>> numeric itself (with prefix-numeric-value)?
>
> Yes.

Also done.

>> In any case, how would you define the semantics for the delete-*
>> actions with numeric values for N?  I mean, for
>> delete-space-after/before I can imagine that the N whitespace
>> characters after/before should survive (in case there are at least so
>> many).  But in case of delete-all-space, there's no precise meaning
>> of the correct spaces around point which could be a wild mix of
>> spaces, tabs, and newlines.
>
> It's not meaningful for delete-all-space, but that's OK.

Ok, so now the N is considered for delete-space-after/before with the
meaning to keep N whitespace characters after/before point and only
delete surplus ones.  However, that has one major drawback: now you
cannot delete all whitespace including newlines before/after point
because that would require you to provide (zerop N) and (< N 0) at the
same time.

What do you think?  I mean, one solution would be to add just more
actions, e.g., rename the ones considering the actual numeric value of N
to delete-all-but-n-space-after/before (plus variants considering
newlines, too) and have delete-space-after/before as previously where
only N positive/negative is checked to control if newlines are
considered or not.

Bye,
Tassilo

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-cycle-spacing.patch --]
[-- Type: text/x-patch, Size: 17165 bytes --]

From 3070409f85f15f63d8da3ad211f825d7a7a648d0 Mon Sep 17 00:00:00 2001
From: Tassilo Horn <tsdh@gnu.org>
Date: Thu, 12 May 2022 23:24:47 +0200
Subject: [PATCH] Improve cycle-spacing

---
 doc/emacs/killing.texi |  25 ++--
 etc/NEWS               |   5 +
 lisp/bindings.el       |   2 +-
 lisp/simple.el         | 277 +++++++++++++++++++++++++++++++----------
 4 files changed, 230 insertions(+), 79 deletions(-)

diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 2fd2d21dd3..30025134eb 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -111,24 +111,27 @@ Deletion
 
 @kindex M-\
 @findex delete-horizontal-space
-@kindex M-SPC
-@findex just-one-space
-@findex cycle-spacing
-  The other delete commands are those that delete only whitespace
+The other delete commands are those that delete only whitespace
 characters: spaces, tabs and newlines.  @kbd{M-\}
 (@code{delete-horizontal-space}) deletes all the spaces and tab
 characters before and after point.  With a prefix argument, this only
-deletes spaces and tab characters before point.  @kbd{M-@key{SPC}}
-(@code{just-one-space}) does likewise but leaves a single space before
+deletes spaces and tab characters before point.
+
+@findex just-one-space
+@code{just-one-space} does likewise but leaves a single space before
 point, regardless of the number of spaces that existed previously
 (even if there were none before).  With a numeric argument @var{n}, it
 leaves @var{n} spaces before point if @var{n} is positive; if @var{n}
 is negative, it deletes newlines in addition to spaces and tabs,
-leaving @minus{}@var{n} spaces before point.  The command @code{cycle-spacing}
-acts like a more flexible version of @code{just-one-space}.  It
-does different things if you call it repeatedly in succession.
-The first call acts like @code{just-one-space}, the next removes
-all whitespace, and a third call restores the original whitespace.
+leaving @minus{}@var{n} spaces before point.
+
+@kindex M-SPC
+@findex cycle-spacing
+@vindex cycle-spacing-actions
+The command @code{cycle-spacing} (@kbd{M-@key{SPC}}) acts like a more
+flexible version of @code{just-one-space}.  It performs different
+space cleanup actions if you call it repeatedly in succession as
+defined by @code{cycle-spacing-actions}.
 
   @kbd{C-x C-o} (@code{delete-blank-lines}) deletes all blank lines
 after the current line.  If the current line is blank, it deletes all
diff --git a/etc/NEWS b/etc/NEWS
index b89771cdbd..bf459793d9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -677,6 +677,11 @@ recreate it anew next time 'imenu' is invoked.
 
 * Editing Changes in Emacs 29.1
 
++++
+** M-SPC is now bound to 'cycle-spacing' (formerly it was 'just-one-space').
+The actions performed by 'cycle-spacing' and their order can now be
+customized via 'cycle-spacing-actions'.
+
 ---
 ** 'scroll-other-window' and 'scroll-other-window-down' now respects remapping.
 These commands (bound to 'C-M-v' and 'C-M-V') used to scroll the other
diff --git a/lisp/bindings.el b/lisp/bindings.el
index bfe5ba8623..ed1325e326 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -990,7 +990,7 @@ esc-map
 (define-key esc-map "\\" 'delete-horizontal-space)
 (define-key esc-map "m" 'back-to-indentation)
 (define-key ctl-x-map "\C-o" 'delete-blank-lines)
-(define-key esc-map " " 'just-one-space)
+(define-key esc-map " " 'cycle-spacing)
 (define-key esc-map "z" 'zap-to-char)
 (define-key esc-map "=" 'count-words-region)
 (define-key ctl-x-map "=" 'what-cursor-position)
diff --git a/lisp/simple.el b/lisp/simple.el
index 3812f6d8c6..5fd9641c34 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1072,15 +1072,24 @@ delete-horizontal-space
   "Delete all spaces and tabs around point.
 If BACKWARD-ONLY is non-nil, delete them only before point."
   (interactive "*P")
+  (delete-space--internal " \t" backward-only))
+
+(defun delete-all-space (&optional backward-only)
+  "Delete all spaces, tabs, and newlines around point.
+If BACKWARD-ONLY is non-nil, delete them only before point."
+  (interactive "*P")
+  (delete-space--internal " \t\r\n" backward-only))
+
+(defun delete-space--internal (chars backward-only)
   (let ((orig-pos (point)))
     (delete-region
      (if backward-only
-	 orig-pos
+         orig-pos
        (progn
-	 (skip-chars-forward " \t")
-	 (constrain-to-field nil orig-pos t)))
+         (skip-chars-forward chars)
+         (constrain-to-field nil orig-pos t)))
      (progn
-       (skip-chars-backward " \t")
+       (skip-chars-backward chars)
        (constrain-to-field nil orig-pos)))))
 
 (defun just-one-space (&optional n)
@@ -1088,73 +1097,207 @@ just-one-space
 If N is negative, delete newlines as well, leaving -N spaces.
 See also `cycle-spacing'."
   (interactive "*p")
-  (cycle-spacing n nil 'single-shot))
+  (let ((orig-pos        (point))
+        (skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
+        (num             (abs (or n 1))))
+    (skip-chars-backward skip-characters)
+    (constrain-to-field nil orig-pos)
+    (let* ((num   (- num (skip-chars-forward " " (+ num (point)))))
+           (mid   (point))
+           (end   (progn
+                    (skip-chars-forward skip-characters)
+                    (constrain-to-field nil orig-pos t))))
+      (delete-region mid end)
+      (insert (make-string num ?\s)))))
 
 (defvar cycle-spacing--context nil
-  "Store context used in consecutive calls to `cycle-spacing' command.
-The first time `cycle-spacing' runs, it saves in this variable:
-its N argument, the original point position, and the original spacing
-around point.")
+  "Stored context used in consecutive calls to `cycle-spacing' command.
+The value is a property list with the following elements:
+- `:orig-pos'    The original position of point when starting the
+                 sequence.
+- `:whitespace-string' All whitespace characters around point
+                       including newlines.
+- `:n'            The prefix arg given to the initial invocation
+                  which is reused for all actions in this cycle.
+- `:last-action'  The last action performed in the cycle.")
+
+(defcustom cycle-spacing-actions
+  '( just-one-space
+     delete-space-after
+     delete-space-before
+     delete-all-space
+     restore)
+  "List of actions cycled through by `cycle-spacing'.
+Supported values are:
+- `just-one-space'      Delete all but N (prefix arg) spaces.
+                        See that command's docstring for details.
+- `delete-space-after'  Delete spaces after point.
+- `delete-space-before' Delete spaces before point.
+- `delete-all-space'    Delete all spaces around point.
+- `restore'             Restore the original spacing.
+
+Also, any function which accepts one numeric argument is allowed.
+
+All actions make use of the numeric prefix arg given to
+`cycle-spacing' in the initial invocation, i.e., `just-one-space'
+keeps this amount of spaces deleting surplus ones.
+`just-one-space' and all other actions have the contract that a
+positive prefix arg (or zero) only deletes tabs and spaces
+whereas a negative prefix arg also deletes newlines.
+
+In addition, an action may take the form (ACTION ARG) where
+ACTION is any action except for `restore' and ARG is either
+- an integer with the meaning that ACTION should always use this
+  fixed integer instead of the actual prefix arg or
+- the symbol `-' with the meaning that ACTION should be performed
+  with the inverted actual prefix arg."
+  :group 'editing-basics
+  :type (let ((actions
+               '((const :tag "Just N (prefix arg) spaces" just-one-space)
+                 (const :tag "Delete spaces after point" delete-space-after)
+                 (const :tag "Delete spaces before point" delete-space-before)
+                 (const :tag "Delete all spaces around point" delete-all-space)
+                 (function :tag "Function receiving a numerig arg"))))
+          `(repeat
+            (choice
+             ,@actions
+             (list :tag "Action with modified arg"
+                   (choice ,@actions)
+                   (choice (const :tag "Inverted prefix arg" -)
+                           (const :tag "Fixed numeric arg" integer)))
+             (const :tag "Restore the original spacing" restore))))
+  :version "29.1")
 
-(defun cycle-spacing (&optional n preserve-nl-back mode)
+(defun cycle-spacing (&optional n)
   "Manipulate whitespace around point in a smart way.
-In interactive use, this function behaves differently in successive
-consecutive calls.
-
-The first call in a sequence acts like `just-one-space'.
-It deletes all spaces and tabs around point, leaving one space
-\(or N spaces).  N is the prefix argument.  If N is negative,
-it deletes newlines as well, leaving -N spaces.
-\(If PRESERVE-NL-BACK is non-nil, it does not delete newlines before point.)
-
-The second call in a sequence deletes all spaces.
-
-The third call in a sequence restores the original whitespace (and point).
-
-If MODE is `single-shot', it performs only the first step in the sequence.
-If MODE is `fast' and the first step would not result in any change
-\(i.e., there are exactly (abs N) spaces around point),
-the function goes straight to the second step.
-
-Repeatedly calling the function with different values of N starts a
-new sequence each time."
-  (interactive "*p")
-  (let ((orig-pos	 (point))
-	(skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
-	(num		 (abs (or n 1))))
-    (skip-chars-backward (if preserve-nl-back " \t" skip-characters))
-    (constrain-to-field nil orig-pos)
-    (cond
-     ;; Command run for the first time, single-shot mode or different argument
-     ((or (eq 'single-shot mode)
-	  (not (equal last-command this-command))
-	  (not cycle-spacing--context)
-	  (not (eq (car cycle-spacing--context) n)))
-      (let* ((start (point))
-	     (num   (- num (skip-chars-forward " " (+ num (point)))))
-	     (mid   (point))
-	     (end   (progn
-		      (skip-chars-forward skip-characters)
-		      (constrain-to-field nil orig-pos t))))
-	(setq cycle-spacing--context  ;; Save for later.
-	      ;; Special handling for case where there was no space at all.
-	      (unless (= start end)
-                (cons n (cons orig-pos (buffer-substring start (point))))))
-	;; If this run causes no change in buffer content, delete all spaces,
-	;; otherwise delete all excess spaces.
-	(delete-region (if (and (eq mode 'fast) (zerop num) (= mid end))
-			   start mid) end)
-        (insert (make-string num ?\s))))
-
-     ;; Command run for the second time.
-     ((not (equal orig-pos (point)))
-      (delete-region (point) orig-pos))
-
-     ;; Command run for the third time.
-     (t
-      (insert (cddr cycle-spacing--context))
-      (goto-char (cadr cycle-spacing--context))
-      (setq cycle-spacing--context nil)))))
+Repeated calls perform the actions in `cycle-spacing-actions' one
+after the other, wrapping around after the last one.
+
+All actions are amendable using a prefix arg N.  In general, a
+zero or positive prefix arg allows only for deletion of tabs and
+spaces whereas a negative prefix arg also allows for deleting
+newlines.
+
+The prefix arg given at the first invocation starting a cycle is
+provided to all following actions, i.e.,
+    \\[negative-argument] \\[cycle-spacing] \\[cycle-spacing] \\[cycle-spacing]
+is equivalent to
+    \\[negative-argument] \\[cycle-spacing] \\[negative-argument] \\[cycle-spacing] \\[negative-argument] \\[cycle-spacing].
+
+A new sequence can be started by providing a different prefix arg
+than provided at the initial invocation (except for 1), or by
+doing any other command before the next \\[cycle-spacing]."
+  (interactive "*P")
+  ;; Initialize `cycle-spacing--context' if needed.
+  (when (or (not (equal last-command this-command))
+            (not cycle-spacing--context)
+            ;; With M-5 M-SPC M-SPC... we pass the prefix arg 5 to
+            ;; each action and only start a new cycle when a different
+            ;; prefix arg is given and which is not the default value
+            ;; 1.
+            (and n (not (equal (plist-get cycle-spacing--context :n)
+                               n))))
+    (let ((orig-pos (point))
+          (skip-characters " \t\n\r"))
+      (save-excursion
+        (skip-chars-backward skip-characters)
+        (constrain-to-field nil orig-pos)
+        (let ((start (point))
+              (end   (progn
+                       (skip-chars-forward skip-characters)
+                       (constrain-to-field nil orig-pos t))))
+          (setq cycle-spacing--context  ;; Save for later.
+                (list :orig-pos orig-pos
+                      :whitespace-string (buffer-substring start end)
+                      :n n
+                      :last-action nil))))))
+
+  ;; Cycle through the actions in `cycle-spacing-actions'.
+  (when cycle-spacing--context
+    (cl-labels ((next-action ()
+                  (let* ((l cycle-spacing-actions)
+                         (elt (plist-get cycle-spacing--context
+                                         :last-action)))
+                    (if (null elt)
+                        (car cycle-spacing-actions)
+                      (catch 'found
+                        (while l
+                          (cond
+                           ((null (cdr l))
+                            (throw 'found
+                                   (when (eq elt (car l))
+                                     (car cycle-spacing-actions))))
+                           ((and (eq elt (car l))
+                                 (cdr l))
+                            (throw 'found (cadr l)))
+                           (t (setq l (cdr l)))))))))
+                (skip-chars (chars max-dist direction)
+                  (if (eq direction 'forward)
+                      (skip-chars-forward
+                       chars
+                       (and max-dist (+ (point) max-dist)))
+                    (skip-chars-backward
+                     chars
+                     (and max-dist (- (point) max-dist)))))
+                (delete-space (n direction)
+                  (let ((orig-point (point)))
+                    (when (or (zerop n)
+                              (not (zerop (skip-chars
+                                           (if (< n 0) " \t\r\n" " \t")
+                                           (abs n) direction))))
+                      (let ((start (point))
+                            (end (progn
+                                   (skip-chars
+                                    (if (< n 0) " \t\r\n" " \t")
+                                    nil direction)
+                                   (point))))
+                        (unless (= start end)
+                          (delete-region start end))
+                        (goto-char (if (eq direction 'forward)
+                                       orig-point
+                                     (+ (abs n) end)))))))
+                (restore ()
+                  (delete-all-space)
+                  (insert (plist-get cycle-spacing--context
+                                     :whitespace-string))
+                  (goto-char (plist-get cycle-spacing--context
+                                        :orig-pos))))
+      (let ((action (next-action)))
+        (atomic-change-group
+          (restore)
+          (unless (eq action 'restore)
+            ;; action can be some-action or (some-action <arg>) where
+            ;; arg is either an integer, the arg to be always used for
+            ;; this action or - to use the inverted context n for this
+            ;; action.
+            (let* ((actual-action (if (listp action)
+                                      (car action)
+                                    action))
+                   (arg (when (listp action)
+                          (nth 1 action)))
+                   (context-n (plist-get cycle-spacing--context :n))
+                   (actual-n (cond
+                              ((integerp arg) arg)
+                              ((eq '- arg)
+                               (* -1 (prefix-numeric-value context-n)))
+                              (t (prefix-numeric-value context-n)))))
+              (cond
+               ((eq actual-action 'just-one-space)
+                (just-one-space actual-n))
+               ((eq actual-action 'delete-space-after)
+                (delete-space actual-n 'forward))
+               ((eq actual-action 'delete-space-before)
+                (delete-space actual-n 'backward))
+               ((eq actual-action 'delete-all-space)
+                (if (< actual-n 0)
+                    (delete-all-space)
+                  (delete-horizontal-space)))
+               ((functionp actual-action)
+                (funcall actual-action actual-n))
+               (t
+                (error "Don't know how to handle action %S" action)))))
+          (setf (plist-get cycle-spacing--context :last-action)
+                action))))))
 \f
 (defun beginning-of-buffer (&optional arg)
   "Move point to the beginning of the buffer.
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-15  9:02                               ` Tassilo Horn
@ 2022-05-15 12:27                                 ` Lars Ingebrigtsen
  2022-05-15 19:04                                   ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-15 12:27 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Robert Pluim, 19267

Tassilo Horn <tsdh@gnu.org> writes:

> Ok, so now the N is considered for delete-space-after/before with the
> meaning to keep N whitespace characters after/before point and only
> delete surplus ones.  However, that has one major drawback: now you
> cannot delete all whitespace including newlines before/after point
> because that would require you to provide (zerop N) and (< N 0) at the
> same time.

Isn't `M--' the magic incantation for deleting newlines for these
commands?  `M--' isn't the same as `C-u -1'...

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-15 12:27                                 ` Lars Ingebrigtsen
@ 2022-05-15 19:04                                   ` Tassilo Horn
  2022-05-16  1:05                                     ` Lars Ingebrigtsen
  2022-05-16  7:33                                     ` Robert Pluim
  0 siblings, 2 replies; 40+ messages in thread
From: Tassilo Horn @ 2022-05-15 19:04 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

[-- Attachment #1: Type: text/plain, Size: 946 bytes --]

Lars Ingebrigtsen <larsi@gnus.org> writes:

>> However, that has one major drawback: now you cannot delete all
>> whitespace including newlines before/after point because that would
>> require you to provide (zerop N) and (< N 0) at the same time.
>
> Isn't `M--' the magic incantation for deleting newlines for these
> commands?  `M--' isn't the same as `C-u -1'...

Indeed, they are not the same but their prefix-numeric-value is the
same.  So now I've made it so that the prefix arg `-' has the general
meaning of including newlines but it's up to the action to decide how it
is interpreted as a number, e.g., just-one-space treats it as -1 as
usual but delete-space-before/after treat it as zero.

New patch attached.  Some final nitpicking please.  And some thoughts
about default value for cycle-spacing-actions.  Maybe only

  (just-one-space delete-all-space restore)

which would mimic the current cycle-spacing behavior?

Bye,
Tassilo


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-cycle-spacing.patch --]
[-- Type: text/x-patch, Size: 18199 bytes --]

From a6a4d973b0905363ce7c560c2ddc7746d2758160 Mon Sep 17 00:00:00 2001
From: Tassilo Horn <tsdh@gnu.org>
Date: Thu, 12 May 2022 23:24:47 +0200
Subject: [PATCH] Improve cycle-spacing

---
 doc/emacs/killing.texi |  25 ++--
 etc/NEWS               |   5 +
 lisp/bindings.el       |   2 +-
 lisp/simple.el         | 295 +++++++++++++++++++++++++++++++----------
 4 files changed, 248 insertions(+), 79 deletions(-)

diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 2fd2d21dd3..30025134eb 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -111,24 +111,27 @@ Deletion
 
 @kindex M-\
 @findex delete-horizontal-space
-@kindex M-SPC
-@findex just-one-space
-@findex cycle-spacing
-  The other delete commands are those that delete only whitespace
+The other delete commands are those that delete only whitespace
 characters: spaces, tabs and newlines.  @kbd{M-\}
 (@code{delete-horizontal-space}) deletes all the spaces and tab
 characters before and after point.  With a prefix argument, this only
-deletes spaces and tab characters before point.  @kbd{M-@key{SPC}}
-(@code{just-one-space}) does likewise but leaves a single space before
+deletes spaces and tab characters before point.
+
+@findex just-one-space
+@code{just-one-space} does likewise but leaves a single space before
 point, regardless of the number of spaces that existed previously
 (even if there were none before).  With a numeric argument @var{n}, it
 leaves @var{n} spaces before point if @var{n} is positive; if @var{n}
 is negative, it deletes newlines in addition to spaces and tabs,
-leaving @minus{}@var{n} spaces before point.  The command @code{cycle-spacing}
-acts like a more flexible version of @code{just-one-space}.  It
-does different things if you call it repeatedly in succession.
-The first call acts like @code{just-one-space}, the next removes
-all whitespace, and a third call restores the original whitespace.
+leaving @minus{}@var{n} spaces before point.
+
+@kindex M-SPC
+@findex cycle-spacing
+@vindex cycle-spacing-actions
+The command @code{cycle-spacing} (@kbd{M-@key{SPC}}) acts like a more
+flexible version of @code{just-one-space}.  It performs different
+space cleanup actions if you call it repeatedly in succession as
+defined by @code{cycle-spacing-actions}.
 
   @kbd{C-x C-o} (@code{delete-blank-lines}) deletes all blank lines
 after the current line.  If the current line is blank, it deletes all
diff --git a/etc/NEWS b/etc/NEWS
index b89771cdbd..bf459793d9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -677,6 +677,11 @@ recreate it anew next time 'imenu' is invoked.
 
 * Editing Changes in Emacs 29.1
 
++++
+** M-SPC is now bound to 'cycle-spacing' (formerly it was 'just-one-space').
+The actions performed by 'cycle-spacing' and their order can now be
+customized via 'cycle-spacing-actions'.
+
 ---
 ** 'scroll-other-window' and 'scroll-other-window-down' now respects remapping.
 These commands (bound to 'C-M-v' and 'C-M-V') used to scroll the other
diff --git a/lisp/bindings.el b/lisp/bindings.el
index bfe5ba8623..ed1325e326 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -990,7 +990,7 @@ esc-map
 (define-key esc-map "\\" 'delete-horizontal-space)
 (define-key esc-map "m" 'back-to-indentation)
 (define-key ctl-x-map "\C-o" 'delete-blank-lines)
-(define-key esc-map " " 'just-one-space)
+(define-key esc-map " " 'cycle-spacing)
 (define-key esc-map "z" 'zap-to-char)
 (define-key esc-map "=" 'count-words-region)
 (define-key ctl-x-map "=" 'what-cursor-position)
diff --git a/lisp/simple.el b/lisp/simple.el
index 3812f6d8c6..75bf465dbf 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1072,15 +1072,24 @@ delete-horizontal-space
   "Delete all spaces and tabs around point.
 If BACKWARD-ONLY is non-nil, delete them only before point."
   (interactive "*P")
+  (delete-space--internal " \t" backward-only))
+
+(defun delete-all-space (&optional backward-only)
+  "Delete all spaces, tabs, and newlines around point.
+If BACKWARD-ONLY is non-nil, delete them only before point."
+  (interactive "*P")
+  (delete-space--internal " \t\r\n" backward-only))
+
+(defun delete-space--internal (chars backward-only)
   (let ((orig-pos (point)))
     (delete-region
      (if backward-only
-	 orig-pos
+         orig-pos
        (progn
-	 (skip-chars-forward " \t")
-	 (constrain-to-field nil orig-pos t)))
+         (skip-chars-forward chars)
+         (constrain-to-field nil orig-pos t)))
      (progn
-       (skip-chars-backward " \t")
+       (skip-chars-backward chars)
        (constrain-to-field nil orig-pos)))))
 
 (defun just-one-space (&optional n)
@@ -1088,73 +1097,225 @@ just-one-space
 If N is negative, delete newlines as well, leaving -N spaces.
 See also `cycle-spacing'."
   (interactive "*p")
-  (cycle-spacing n nil 'single-shot))
+  (let ((orig-pos        (point))
+        (skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
+        (num             (abs (or n 1))))
+    (skip-chars-backward skip-characters)
+    (constrain-to-field nil orig-pos)
+    (let* ((num   (- num (skip-chars-forward " " (+ num (point)))))
+           (mid   (point))
+           (end   (progn
+                    (skip-chars-forward skip-characters)
+                    (constrain-to-field nil orig-pos t))))
+      (delete-region mid end)
+      (insert (make-string num ?\s)))))
 
 (defvar cycle-spacing--context nil
-  "Store context used in consecutive calls to `cycle-spacing' command.
-The first time `cycle-spacing' runs, it saves in this variable:
-its N argument, the original point position, and the original spacing
-around point.")
+  "Stored context used in consecutive calls to `cycle-spacing' command.
+The value is a property list with the following elements:
+- `:orig-pos'    The original position of point when starting the
+                 sequence.
+- `:whitespace-string' All whitespace characters around point
+                       including newlines.
+- `:n'            The prefix arg given to the initial invocation
+                  which is reused for all actions in this cycle.
+- `:last-action'  The last action performed in the cycle.")
+
+(defcustom cycle-spacing-actions
+  '( just-one-space
+     delete-space-after
+     delete-space-before
+     delete-all-space
+     restore)
+  "List of actions cycled through by `cycle-spacing'.
+Supported values are:
+- `just-one-space'      Delete all but N (prefix arg) spaces.
+                        See that command's docstring for details.
+- `delete-space-after'  Delete spaces after point keeping only N.
+- `delete-space-before' Delete spaces before point keeping only N.
+- `delete-all-space'    Delete all spaces around point.
+- `restore'             Restore the original spacing.
+
+All actions make use of the prefix arg given to `cycle-spacing'
+in the initial invocation, i.e., `just-one-space' keeps this
+amount of spaces deleting surplus ones.  `just-one-space' and all
+other actions have the contract that a positive prefix arg (or
+zero) only deletes tabs and spaces whereas a negative prefix arg
+also deletes newlines.
+
+The `delete-space-before' and `delete-space-after' actions handle
+the prefix arg \\[negative-argument] without a number provided
+specially: all spaces before/after point are deleted (as if N was
+0) including newlines (as if N was negative).
+
+In addition to the predefined actions listed above, any function
+which accepts one argument is allowed.  It receives the raw
+prefix arg of this cycle.
+
+In addition, an action may take the form (ACTION ARG) where
+ACTION is any action except for `restore' and ARG is either
+- an integer with the meaning that ACTION should always use this
+  fixed integer instead of the actual prefix arg or
+- the symbol `inverted-arg' with the meaning that ACTION should
+  be performed with the inverted actual prefix arg.
+- the symbol `-' with the meaning that ACTION should include
+  newlines but it's up to the ACTION to decide how to interpret
+  it as a number, e.g., `delete-space-before' and
+  `delete-space-after' treat it like 0 whereas `just-one-space'
+  treats it like -1 as is usual."
+  :group 'editing-basics
+  :type (let ((actions
+               '((const :tag "Just N (prefix arg) spaces" just-one-space)
+                 (const :tag "Delete spaces after point" delete-space-after)
+                 (const :tag "Delete spaces before point" delete-space-before)
+                 (const :tag "Delete all spaces around point" delete-all-space)
+                 (function :tag "Function receiving a numerig arg"))))
+          `(repeat
+            (choice
+             ,@actions
+             (list :tag "Action with modified arg"
+                   (choice ,@actions)
+                   (choice (const :tag "Inverted prefix arg" inverted-arg)
+                           (const :tag "Fixed numeric arg" integer)))
+             (const :tag "Restore the original spacing" restore))))
+  :version "29.1")
 
-(defun cycle-spacing (&optional n preserve-nl-back mode)
+(defun cycle-spacing (&optional n)
   "Manipulate whitespace around point in a smart way.
-In interactive use, this function behaves differently in successive
-consecutive calls.
-
-The first call in a sequence acts like `just-one-space'.
-It deletes all spaces and tabs around point, leaving one space
-\(or N spaces).  N is the prefix argument.  If N is negative,
-it deletes newlines as well, leaving -N spaces.
-\(If PRESERVE-NL-BACK is non-nil, it does not delete newlines before point.)
-
-The second call in a sequence deletes all spaces.
-
-The third call in a sequence restores the original whitespace (and point).
-
-If MODE is `single-shot', it performs only the first step in the sequence.
-If MODE is `fast' and the first step would not result in any change
-\(i.e., there are exactly (abs N) spaces around point),
-the function goes straight to the second step.
-
-Repeatedly calling the function with different values of N starts a
-new sequence each time."
-  (interactive "*p")
-  (let ((orig-pos	 (point))
-	(skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
-	(num		 (abs (or n 1))))
-    (skip-chars-backward (if preserve-nl-back " \t" skip-characters))
-    (constrain-to-field nil orig-pos)
-    (cond
-     ;; Command run for the first time, single-shot mode or different argument
-     ((or (eq 'single-shot mode)
-	  (not (equal last-command this-command))
-	  (not cycle-spacing--context)
-	  (not (eq (car cycle-spacing--context) n)))
-      (let* ((start (point))
-	     (num   (- num (skip-chars-forward " " (+ num (point)))))
-	     (mid   (point))
-	     (end   (progn
-		      (skip-chars-forward skip-characters)
-		      (constrain-to-field nil orig-pos t))))
-	(setq cycle-spacing--context  ;; Save for later.
-	      ;; Special handling for case where there was no space at all.
-	      (unless (= start end)
-                (cons n (cons orig-pos (buffer-substring start (point))))))
-	;; If this run causes no change in buffer content, delete all spaces,
-	;; otherwise delete all excess spaces.
-	(delete-region (if (and (eq mode 'fast) (zerop num) (= mid end))
-			   start mid) end)
-        (insert (make-string num ?\s))))
-
-     ;; Command run for the second time.
-     ((not (equal orig-pos (point)))
-      (delete-region (point) orig-pos))
-
-     ;; Command run for the third time.
-     (t
-      (insert (cddr cycle-spacing--context))
-      (goto-char (cadr cycle-spacing--context))
-      (setq cycle-spacing--context nil)))))
+Repeated calls perform the actions in `cycle-spacing-actions' one
+after the other, wrapping around after the last one.
+
+All actions are amendable using a prefix arg N.  In general, a
+zero or positive prefix arg allows only for deletion of tabs and
+spaces whereas a negative prefix arg also allows for deleting
+newlines.
+
+The prefix arg given at the first invocation starting a cycle is
+provided to all following actions, i.e.,
+    \\[negative-argument] \\[cycle-spacing] \\[cycle-spacing] \\[cycle-spacing]
+is equivalent to
+    \\[negative-argument] \\[cycle-spacing] \\[negative-argument] \\[cycle-spacing] \\[negative-argument] \\[cycle-spacing].
+
+A new sequence can be started by providing a different prefix arg
+than provided at the initial invocation (except for 1), or by
+doing any other command before the next \\[cycle-spacing]."
+  (interactive "*P")
+  ;; Initialize `cycle-spacing--context' if needed.
+  (when (or (not (equal last-command this-command))
+            (not cycle-spacing--context)
+            ;; With M-5 M-SPC M-SPC... we pass the prefix arg 5 to
+            ;; each action and only start a new cycle when a different
+            ;; prefix arg is given and which is not the default value
+            ;; 1.
+            (and n (not (equal (plist-get cycle-spacing--context :n)
+                               n))))
+    (let ((orig-pos (point))
+          (skip-characters " \t\n\r"))
+      (save-excursion
+        (skip-chars-backward skip-characters)
+        (constrain-to-field nil orig-pos)
+        (let ((start (point))
+              (end   (progn
+                       (skip-chars-forward skip-characters)
+                       (constrain-to-field nil orig-pos t))))
+          (setq cycle-spacing--context  ;; Save for later.
+                (list :orig-pos orig-pos
+                      :whitespace-string (buffer-substring start end)
+                      :n n
+                      :last-action nil))))))
+
+  ;; Cycle through the actions in `cycle-spacing-actions'.
+  (when cycle-spacing--context
+    (cl-labels ((next-action ()
+                  (let* ((l cycle-spacing-actions)
+                         (elt (plist-get cycle-spacing--context
+                                         :last-action)))
+                    (if (null elt)
+                        (car cycle-spacing-actions)
+                      (catch 'found
+                        (while l
+                          (cond
+                           ((null (cdr l))
+                            (throw 'found
+                                   (when (eq elt (car l))
+                                     (car cycle-spacing-actions))))
+                           ((and (eq elt (car l))
+                                 (cdr l))
+                            (throw 'found (cadr l)))
+                           (t (setq l (cdr l)))))))))
+                (skip-chars (chars max-dist direction)
+                  (if (eq direction 'forward)
+                      (skip-chars-forward
+                       chars
+                       (and max-dist (+ (point) max-dist)))
+                    (skip-chars-backward
+                     chars
+                     (and max-dist (- (point) max-dist)))))
+                (delete-space (n include-newlines direction)
+                  (let ((orig-point (point))
+                        (chars (if include-newlines
+                                   " \t\r\n"
+                                 " \t")))
+                    (when (or (zerop n)
+                              (= n (abs (skip-chars chars n direction))))
+                      (let ((start (point))
+                            (end (progn
+                                   (skip-chars chars nil direction)
+                                   (point))))
+                        (unless (= start end)
+                          (delete-region start end))
+                        (goto-char (if (eq direction 'forward)
+                                       orig-point
+                                     (+ n end)))))))
+                (restore ()
+                  (delete-all-space)
+                  (insert (plist-get cycle-spacing--context
+                                     :whitespace-string))
+                  (goto-char (plist-get cycle-spacing--context
+                                        :orig-pos))))
+      (let ((action (next-action)))
+        (atomic-change-group
+          (restore)
+          (unless (eq action 'restore)
+            ;; action can be some-action or (some-action <arg>) where
+            ;; arg is either an integer, the arg to be always used for
+            ;; this action or - to use the inverted context n for this
+            ;; action.
+            (let* ((actual-action (if (listp action)
+                                      (car action)
+                                    action))
+                   (arg (when (listp action)
+                          (nth 1 action)))
+                   (context-n (plist-get cycle-spacing--context :n))
+                   (actual-n (cond
+                              ((integerp arg) arg)
+                              ((eq 'inverted-arg arg)
+                               (* -1 (prefix-numeric-value context-n)))
+                              ((eq '- arg) '-)
+                              (t context-n)))
+                   (numeric-n (prefix-numeric-value actual-n))
+                   (include-newlines (and actual-n
+                                          (or (eq actual-n '-)
+                                              (< actual-n 0)))))
+              (cond
+               ((eq actual-action 'just-one-space)
+                (just-one-space numeric-n))
+               ((eq actual-action 'delete-space-after)
+                (delete-space (if (eq actual-n '-) 0 (abs numeric-n))
+                              include-newlines 'forward))
+               ((eq actual-action 'delete-space-before)
+                (delete-space (if (eq actual-n '-) 0 (abs numeric-n))
+                              include-newlines 'backward))
+               ((eq actual-action 'delete-all-space)
+                (if include-newlines
+                    (delete-all-space)
+                  (delete-horizontal-space)))
+               ((functionp actual-action)
+                (funcall actual-action actual-n))
+               (t
+                (error "Don't know how to handle action %S" action)))))
+          (setf (plist-get cycle-spacing--context :last-action)
+                action))))))
 \f
 (defun beginning-of-buffer (&optional arg)
   "Move point to the beginning of the buffer.
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-15 19:04                                   ` Tassilo Horn
@ 2022-05-16  1:05                                     ` Lars Ingebrigtsen
  2022-05-16  8:05                                       ` Tassilo Horn
  2022-05-16  7:33                                     ` Robert Pluim
  1 sibling, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-16  1:05 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Robert Pluim, 19267

Tassilo Horn <tsdh@gnu.org> writes:

> New patch attached.  Some final nitpicking please.  And some thoughts
> about default value for cycle-spacing-actions.  Maybe only
>
>   (just-one-space delete-all-space restore)
>
> which would mimic the current cycle-spacing behavior?

Yes, I think that would be good.

I don't really have any nitpicks -- skimming the patch, it looks fine to
me (but I didn't actually test it).  Feel free to push when you want to,
and I'll see whether I find any nits when using it.  😀

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-15 19:04                                   ` Tassilo Horn
  2022-05-16  1:05                                     ` Lars Ingebrigtsen
@ 2022-05-16  7:33                                     ` Robert Pluim
  1 sibling, 0 replies; 40+ messages in thread
From: Robert Pluim @ 2022-05-16  7:33 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Lars Ingebrigtsen, 19267

>>>>> On Sun, 15 May 2022 21:04:05 +0200, Tassilo Horn <tsdh@gnu.org> said:

    Tassilo> Lars Ingebrigtsen <larsi@gnus.org> writes:
    >>> However, that has one major drawback: now you cannot delete all
    >>> whitespace including newlines before/after point because that would
    >>> require you to provide (zerop N) and (< N 0) at the same time.
    >> 
    >> Isn't `M--' the magic incantation for deleting newlines for these
    >> commands?  `M--' isn't the same as `C-u -1'...

    Tassilo> Indeed, they are not the same but their prefix-numeric-value is the
    Tassilo> same.  So now I've made it so that the prefix arg `-' has the general
    Tassilo> meaning of including newlines but it's up to the action to decide how it
    Tassilo> is interpreted as a number, e.g., just-one-space treats it as -1 as
    Tassilo> usual but delete-space-before/after treat it as zero.

    Tassilo> New patch attached.  Some final nitpicking please.  And some thoughts
    Tassilo> about default value for cycle-spacing-actions.  Maybe only

    Tassilo>   (just-one-space delete-all-space restore)

    Tassilo> which would mimic the current cycle-spacing behavior?

Yes, I think thatʼs best. Having five options in the default value
seems a bit too much.

Thanks for working on this.

Robert
-- 





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-16  1:05                                     ` Lars Ingebrigtsen
@ 2022-05-16  8:05                                       ` Tassilo Horn
  2022-05-16 12:19                                         ` Lars Ingebrigtsen
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-16  8:05 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

Lars Ingebrigtsen <larsi@gnus.org> writes:

>> New patch attached.  Some final nitpicking please.  And some thoughts
>> about default value for cycle-spacing-actions.  Maybe only
>>
>>   (just-one-space delete-all-space restore)
>>
>> which would mimic the current cycle-spacing behavior?
>
> Yes, I think that would be good.

Ok, Robert also agreed to this option.

> I don't really have any nitpicks -- skimming the patch, it looks fine
> to me (but I didn't actually test it).  Feel free to push when you
> want to, and I'll see whether I find any nits when using it.  😀

It's pushed.  And obviously I've seen that I've forgotten the "perform
action as if M-- was given" modifier in the defcustom afterwards which
is now also added in another commit.

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-16  8:05                                       ` Tassilo Horn
@ 2022-05-16 12:19                                         ` Lars Ingebrigtsen
  2022-05-16 12:28                                           ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-16 12:19 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Robert Pluim, 19267

Tassilo Horn <tsdh@gnu.org> writes:

> It's pushed.  And obviously I've seen that I've forgotten the "perform
> action as if M-- was given" modifier in the defcustom afterwards which
> is now also added in another commit.

Thanks; works great.  I now have

(setq cycle-spacing-actions '((just-one-space -) delete-all-space restore))

which makes `M-SPC' do exactly what I want.

With "emacs -Q', though, and:

`C-u M-SPC'

Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p (4))
  cycle-spacing((4))
  funcall-interactively(cycle-spacing (4))
  call-interactively(cycle-spacing nil nil)
  command-execute(cycle-spacing)

`C-u 4 M-SPC' works fine.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-16 12:19                                         ` Lars Ingebrigtsen
@ 2022-05-16 12:28                                           ` Tassilo Horn
  2022-05-16 12:32                                             ` Lars Ingebrigtsen
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-16 12:28 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267

Lars Ingebrigtsen <larsi@gnus.org> writes:

Hi Lars,

>> It's pushed.  And obviously I've seen that I've forgotten the
>> "perform action as if M-- was given" modifier in the defcustom
>> afterwards which is now also added in another commit.
>
> Thanks; works great.  I now have
>
> (setq cycle-spacing-actions '((just-one-space -) delete-all-space restore))
>
> which makes `M-SPC' do exactly what I want.

Perfect!

> With "emacs -Q', though, and:
>
> `C-u M-SPC'
>
> Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p (4))
>   cycle-spacing((4))
>   funcall-interactively(cycle-spacing (4))
>   call-interactively(cycle-spacing nil nil)
>   command-execute(cycle-spacing)
>
> `C-u 4 M-SPC' works fine.

Ah, yes, (repeated) C-us with no number hasn't been handled properly.
I've just pushed a change fixing that.

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-16 12:28                                           ` Tassilo Horn
@ 2022-05-16 12:32                                             ` Lars Ingebrigtsen
  2022-05-16 13:04                                               ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Lars Ingebrigtsen @ 2022-05-16 12:32 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Robert Pluim, 19267

Tassilo Horn <tsdh@gnu.org> writes:

> Ah, yes, (repeated) C-us with no number hasn't been handled properly.
> I've just pushed a change fixing that.

Thanks; I can confirm that this fixes that issue, too, so `M-SPC' is now
officially perfect.  😀

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-16 12:32                                             ` Lars Ingebrigtsen
@ 2022-05-16 13:04                                               ` Tassilo Horn
  2022-05-17 15:42                                                 ` Robert Pluim
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-16 13:04 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Robert Pluim, 19267-done

Lars Ingebrigtsen <larsi@gnus.org> writes:

>> Ah, yes, (repeated) C-us with no number hasn't been handled properly.
>> I've just pushed a change fixing that.
>
> Thanks; I can confirm that this fixes that issue, too, so `M-SPC' is
> now officially perfect.  😀

Phew! 😅
Then I'm closing this issue.

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-16 13:04                                               ` Tassilo Horn
@ 2022-05-17 15:42                                                 ` Robert Pluim
  2022-05-17 15:55                                                   ` Robert Pluim
  0 siblings, 1 reply; 40+ messages in thread
From: Robert Pluim @ 2022-05-17 15:42 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Lars Ingebrigtsen, 19267

>>>>> On Mon, 16 May 2022 15:04:20 +0200, Tassilo Horn <tsdh@gnu.org> said:

    Tassilo> Lars Ingebrigtsen <larsi@gnus.org> writes:
    >>> Ah, yes, (repeated) C-us with no number hasn't been handled properly.
    >>> I've just pushed a change fixing that.
    >> 
    >> Thanks; I can confirm that this fixes that issue, too, so `M-SPC' is
    >> now officially perfect.  😀

    Tassilo> Phew! 😅
    Tassilo> Then I'm closing this issue.

There was a small mistake in the defcustom of 'cycle-spacing-actions',
but Iʼve just fixed that with 45ec56f5bd

Robert
-- 





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-17 15:42                                                 ` Robert Pluim
@ 2022-05-17 15:55                                                   ` Robert Pluim
  2022-05-17 15:57                                                     ` Tassilo Horn
  0 siblings, 1 reply; 40+ messages in thread
From: Robert Pluim @ 2022-05-17 15:55 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Lars Ingebrigtsen, 19267

>>>>> On Tue, 17 May 2022 17:42:08 +0200, Robert Pluim <rpluim@gmail.com> said:

>>>>> On Mon, 16 May 2022 15:04:20 +0200, Tassilo Horn <tsdh@gnu.org> said:
    Tassilo> Lars Ingebrigtsen <larsi@gnus.org> writes:
    >>>> Ah, yes, (repeated) C-us with no number hasn't been handled properly.
    >>>> I've just pushed a change fixing that.
    >>> 
    >>> Thanks; I can confirm that this fixes that issue, too, so `M-SPC' is
    >>> now officially perfect.  😀

    Tassilo> Phew! 😅
    Tassilo> Then I'm closing this issue.

    Robert> There was a small mistake in the defcustom of 'cycle-spacing-actions',
    Robert> but Iʼve just fixed that with 45ec56f5bd

Btw, the reason I noticed this is because I wanted to use
'(delete-all-space -1), meaning delete all space including newlines,
but then leave one space, but I guess thatʼs not supported, so Iʼll
just have to use a function which does '(insert " ") afterwards.

Robert
-- 





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-17 15:55                                                   ` Robert Pluim
@ 2022-05-17 15:57                                                     ` Tassilo Horn
  2022-05-17 16:12                                                       ` Robert Pluim
  0 siblings, 1 reply; 40+ messages in thread
From: Tassilo Horn @ 2022-05-17 15:57 UTC (permalink / raw)
  To: Robert Pluim; +Cc: Lars Ingebrigtsen, 19267

Robert Pluim <rpluim@gmail.com> writes:

Hi Robert,

>     Robert> There was a small mistake in the defcustom of 'cycle-spacing-actions',
>     Robert> but Iʼve just fixed that with 45ec56f5bd

Oh, indeed, good catch.  Thanks a lot!

> Btw, the reason I noticed this is because I wanted to use
> '(delete-all-space -1), meaning delete all space including newlines,
> but then leave one space, but I guess thatʼs not supported,

Isn't that exactly what (just-one-space -1) would do?

> so Iʼll just have to use a function which does '(insert " ")
> afterwards.

Hey, it's great that you now *can* do it, right? ;-)

Bye,
Tassilo





^ permalink raw reply	[flat|nested] 40+ messages in thread

* bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted
  2022-05-17 15:57                                                     ` Tassilo Horn
@ 2022-05-17 16:12                                                       ` Robert Pluim
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Pluim @ 2022-05-17 16:12 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: Lars Ingebrigtsen, 19267

>>>>> On Tue, 17 May 2022 17:57:48 +0200, Tassilo Horn <tsdh@gnu.org> said:

    Tassilo> Robert Pluim <rpluim@gmail.com> writes:
    Tassilo> Hi Robert,

    Robert> There was a small mistake in the defcustom of 'cycle-spacing-actions',
    Robert> but Iʼve just fixed that with 45ec56f5bd

    Tassilo> Oh, indeed, good catch.  Thanks a lot!

    >> Btw, the reason I noticed this is because I wanted to use
    >> '(delete-all-space -1), meaning delete all space including newlines,
    >> but then leave one space, but I guess thatʼs not supported,

    Tassilo> Isn't that exactly what (just-one-space -1) would do?

d'oh. Yes, thanks

    >> so Iʼll just have to use a function which does '(insert " ")
    >> afterwards.

    Tassilo> Hey, it's great that you now *can* do it, right? ;-)

Absolutely.

Robert
-- 





^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2022-05-17 16:12 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-04  8:06 bug#19267: 25.0.50; Enhance cycle-spacing with a state where only whitespace after point is deleted Tassilo Horn
2022-05-12  2:16 ` Lars Ingebrigtsen
2022-05-12  4:53   ` Tassilo Horn
2022-05-12 11:45     ` Lars Ingebrigtsen
2022-05-12 11:56       ` Tassilo Horn
2022-05-12 12:09         ` Lars Ingebrigtsen
2022-05-12 12:16           ` Robert Pluim
2022-05-12 12:21             ` Lars Ingebrigtsen
2022-05-12 14:45               ` Tassilo Horn
2022-05-13  8:50                 ` Tassilo Horn
2022-05-13 13:33                   ` Robert Pluim
2022-05-13 18:48                     ` Tassilo Horn
2022-05-13 12:19                 ` Lars Ingebrigtsen
2022-05-13 13:36                   ` Robert Pluim
2022-05-13 13:39                     ` Lars Ingebrigtsen
2022-05-13 19:01                   ` Tassilo Horn
2022-05-13 19:26                     ` Lars Ingebrigtsen
2022-05-13 21:11                       ` Tassilo Horn
2022-05-14  2:24                         ` Lars Ingebrigtsen
2022-05-14  6:54                           ` Tassilo Horn
2022-05-14 15:51                             ` Lars Ingebrigtsen
2022-05-15  9:02                               ` Tassilo Horn
2022-05-15 12:27                                 ` Lars Ingebrigtsen
2022-05-15 19:04                                   ` Tassilo Horn
2022-05-16  1:05                                     ` Lars Ingebrigtsen
2022-05-16  8:05                                       ` Tassilo Horn
2022-05-16 12:19                                         ` Lars Ingebrigtsen
2022-05-16 12:28                                           ` Tassilo Horn
2022-05-16 12:32                                             ` Lars Ingebrigtsen
2022-05-16 13:04                                               ` Tassilo Horn
2022-05-17 15:42                                                 ` Robert Pluim
2022-05-17 15:55                                                   ` Robert Pluim
2022-05-17 15:57                                                     ` Tassilo Horn
2022-05-17 16:12                                                       ` Robert Pluim
2022-05-16  7:33                                     ` Robert Pluim
2022-05-12 12:20           ` Tassilo Horn
2022-05-12  5:40   ` Eli Zaretskii
2022-05-12  5:46     ` Tassilo Horn
2022-05-12  8:25     ` Robert Pluim
2022-05-12  8:29       ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).