* 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 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: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-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 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-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 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 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-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
* 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-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 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
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 external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.