diff --git a/CONTRIBUTE b/CONTRIBUTE index 0ab45a99ee2..aaf26ece5a7 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -276,10 +276,11 @@ formatting them: - Emacs follows the GNU coding standards for ChangeLog entries: see https://www.gnu.org/prep/standards/html_node/Change-Logs.html or run - 'info "(standards)Change Logs"'. One exception is that commits - still sometimes quote `like-this' (as the standards used to - recommend) rather than 'like-this' or ‘like this’ (as they do now), - as `...' is so widely used elsewhere in Emacs. + 'info "(standards)Change Logs"'. One exception is that commits still + sometimes quote `like-this' (as the standards used to recommend) + rather than 'like-this' or ‘like this’ (as they do now), as `...' is + so widely used elsewhere in Emacs. (Please do not use the Markdown + convention of quoting `like this`.) - Some commenting rules in the GNU coding standards also apply to ChangeLog entries: they must be in English, and be complete diff --git a/admin/authors.el b/admin/authors.el index a7c5938fdad..03364e3e08d 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -97,6 +97,7 @@ files.") ("Earl Hyatt" "Earl" "ej32u@protonmail\\.com") ("Ed L. Cashin" "Ed L Cashin") ("Edward M. Reingold" "Ed\\(ward\\( M\\)?\\)? Reingold" "Reingold Edward M") + ("Elías Gabriel Pérez" "eg642616@gmail\\.com") ; bug#76319 ("Emilio C. Lopes" "Emilio Lopes") ("Eric M. Ludlam" "Eric Ludlam") ("Eric S. Raymond" "Eric Raymond") diff --git a/build-aux/git-hooks/commit-msg b/build-aux/git-hooks/commit-msg index a8ae70d49d3..a52862bf745 100755 --- a/build-aux/git-hooks/commit-msg +++ b/build-aux/git-hooks/commit-msg @@ -92,6 +92,11 @@ exec $awk \ status = 1 } + /(^|[^\\])`[^'\''`]+`/ { + print "Markdown-style quotes in commit message" + status = 1 + } + nlines == 0 && $0 !~ non_space { next } { nlines++ } diff --git a/build-aux/git-hooks/prepare-commit-msg b/build-aux/git-hooks/prepare-commit-msg index eefecaa1556..e8243e157cd 100755 --- a/build-aux/git-hooks/prepare-commit-msg +++ b/build-aux/git-hooks/prepare-commit-msg @@ -33,17 +33,17 @@ else awk="awk" fi -exec $awk ' +exec $awk " # Catch the case when someone ran git-commit with -s option, # which automatically adds Signed-off-by. /^Signed-off-by: / { - print "'\''Signed-off-by:'\'' in commit message" + print \"'Signed-off-by:' in commit message\" status = 1 } END { if (status != 0) { - print "Commit aborted; please see the file 'CONTRIBUTE'" + print \"Commit aborted; please see the file 'CONTRIBUTE'\" } exit status } -' <"$COMMIT_MSG_FILE" +" <"$COMMIT_MSG_FILE" diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index 9b6f7cd8f31..857584b9933 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -35,8 +35,6 @@ install or uninstall packages via this buffer. @xref{Package Menu}. name of a package, and displays a help buffer describing the attributes of the package and the features that it implements. -@cindex GNU ELPA -@cindex NonGNU ELPA By default, Emacs downloads packages from two archives: @url{https://elpa.gnu.org/, GNU ELPA} and @url{https://elpa.nongnu.org/, NonGNU ELPA}. These are maintained by the Emacs developers and hosted @@ -400,6 +398,8 @@ package is somehow unavailable, Emacs signals an error and stops installation.) A package's requirements list is shown in its help buffer. +@cindex GNU ELPA +@cindex NonGNU ELPA By default, Emacs downloads packages from two archives: @url{https://elpa.gnu.org/, GNU ELPA} and @url{https://elpa.nongnu.org/, NonGNU ELPA}. These are maintained by the Emacs developers and hosted @@ -420,6 +420,7 @@ name of the package archive directory. You can alter this list if you wish to use third party package archives---but do so at your own risk, and use only third parties that you think you can trust! +@cindex base location, package archive @defopt package-archives The value of this variable is an alist of package archives recognized by the Emacs package manager. diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index fc52f11cf4a..17fa1e05fee 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -409,6 +409,26 @@ if so, @code{nil} otherwise. The argument must be a number. @code{(zerop x)} is equivalent to @code{(= x 0)}. @end defun +@defun plusp number +This predicate tests whether its argument is positive, and returns +@code{t} if so, @code{nil} otherwise. The argument must be a number. +@end defun + +@defun minusp number +This predicate tests whether its argument is negative, and returns +@code{t} if so, @code{nil} otherwise. The argument must be a number. +@end defun + +@defun oddp integer +This predicate tests whether its argument is an odd number, and returns +@code{t} if so, @code{nil} otherwise. The argument must be an integer. +@end defun + +@defun evenp integer +This predicate tests whether its argument is an even number, and returns +@code{t} if so, @code{nil} otherwise. The argument must be an integer. +@end defun + @node Comparison of Numbers @section Comparison of Numbers @cindex number comparison diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index 48b8ea09c65..029f11f520d 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -233,32 +233,6 @@ cl-callf cl-callf2 cl-defsubst cl-letf cl-letf* @end example -@c This is not uninteresting I suppose, but is of zero practical relevance -@c to the user, and seems like a hostage to changing implementation details. -The following simple functions and macros are defined in @file{cl-lib.el}; -they do not cause other components like @file{cl-extra} to be loaded. - -@example -cl-evenp cl-oddp cl-minusp -cl-plusp cl-endp cl-subst -cl-copy-list cl-list* cl-ldiff -cl-rest cl-decf [1] cl-incf [1] -cl-acons cl-adjoin [2] cl-pairlis -cl-pushnew [1,2] cl-declaim cl-proclaim -cl-caaar@dots{}cl-cddddr cl-first@dots{}cl-tenth -cl-mapcar [3] -@end example - -@noindent -[1] Only when @var{place} is a plain variable name. - -@noindent -[2] Only if @code{:test} is @code{eq}, @code{equal}, or unspecified, -and @code{:key} is not used. - -@noindent -[3] Only for one sequence argument or two list arguments. - @node Printing @chapter Printing @@ -2476,7 +2450,7 @@ by the name @code{it} in the ``then'' part. For example: (setq funny-numbers '(6 13 -1)) @result{} (6 13 -1) (cl-loop for x below 10 - if (cl-oddp x) + if (oddp x) collect x into odds and if (memq x funny-numbers) return (cdr it) end else @@ -3081,7 +3055,7 @@ This section defines a few simple Common Lisp operations on numbers that were left out of Emacs Lisp. @menu -* Predicates on Numbers:: @code{cl-plusp}, @code{cl-oddp}, etc. +* Predicates on Numbers:: @code{cl-digit-char-p}, etc. * Numerical Functions:: @code{cl-floor}, @code{cl-ceiling}, etc. * Random Numbers:: @code{cl-random}, @code{cl-make-random-state}. * Implementation Parameters:: @code{cl-most-positive-float}, etc. @@ -3094,26 +3068,6 @@ that were left out of Emacs Lisp. These functions return @code{t} if the specified condition is true of the numerical argument, or @code{nil} otherwise. -@defun cl-plusp number -This predicate tests whether @var{number} is positive. It is an -error if the argument is not a number. -@end defun - -@defun cl-minusp number -This predicate tests whether @var{number} is negative. It is an -error if the argument is not a number. -@end defun - -@defun cl-oddp integer -This predicate tests whether @var{integer} is odd. It is an -error if the argument is not an integer. -@end defun - -@defun cl-evenp integer -This predicate tests whether @var{integer} is even. It is an -error if the argument is not an integer. -@end defun - @defun cl-digit-char-p char radix Test if @var{char} is a digit in the specified @var{radix} (default is 10). If it is, return the numerical value of digit @var{char} in diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index ac0bb63335c..86ffba29744 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -955,10 +955,9 @@ This is another method from the Kerberos suite. It behaves like @cindex @option{plink} method @item @option{plink} -@option{plink} method is for MS Windows users with the -PuTTY@footnote{It requires at least PuTTY 0.82.} implementation of -SSH@. It uses @samp{plink -ssh} to log in to the remote host. It -supports changing the remote login shell @command{/bin/sh}. +@option{plink} method is for MS Windows users with the PuTTY +implementation of SSH@. It uses @samp{plink -ssh} to log in to the +remote host. It supports changing the remote login shell @command{/bin/sh}. Check the @samp{Share SSH connections if possible} control for that session. @@ -1191,8 +1190,7 @@ This method supports the @samp{-p} argument. These methods are similar to @option{scp} or @option{sftp}, but they use the @command{plink} command to connect to the remote host, and they use @command{pscp} or @command{psftp} for transferring the files. -These programs are part of PuTTY@footnote{It requires at least PuTTY -0.82.}, an SSH implementation for MS Windows. +These programs are part of PuTTY, an SSH implementation for MS Windows. They support changing the remote login shell @command{/bin/sh}. diff --git a/etc/AUTHORS b/etc/AUTHORS index 03f6b15a1a2..576dfa2e087 100644 --- a/etc/AUTHORS +++ b/etc/AUTHORS @@ -355,7 +355,7 @@ Andreas Rottmann: changed emacsclient.1 emacsclient.c misc.texi server.el Andreas Schwab: changed configure.ac lisp.h xdisp.c process.c alloc.c coding.c Makefile.in emacs.c files.el fileio.c keyboard.c fns.c lread.c xterm.c src/Makefile.in editfns.c print.c eval.c font.c xfns.c sysdep.c - and 663 other files + and 664 other files Andreas Seltenreich: changed nnweb.el gnus.texi message.el gnus-sum.el gnus.el nnslashdot.el gnus-srvr.el gnus-util.el mm-url.el mm-uu.el @@ -474,11 +474,11 @@ Antoine Beaupré: changed vc-git.el Antoine Kalmbach: changed README.md eglot.el -Antoine Levitt: changed gnus-group.el gnus-sum.el message.texi +Antoine Levitt: changed gnus-group.el gnus-sum.el message.texi ada-prj.el ange-ftp.el cus-edit.el dired-x.el ebnf2ps.el emerge.el erc-button.el erc-goodies.el erc-stamp.el erc-track.el files.el find-file.el gnus-art.el gnus-uu.el gnus.el gnus.texi message.el mh-funcs.el - mh-mime.el and 8 other files + and 9 other files Antonin Houska: changed newcomment.el @@ -748,7 +748,7 @@ and changed fill.el simple.el indent.el paragraphs.el cmds.c intervals.c text-mode.el textprop.c ada.el allout.el awk-mode.el bibtex.el buffer.c buffer.h c-mode.el and 38 other files -Boris Samorodov: changed net/imap.el +Boris Samorodov: changed imap.el Boruch Baum: co-wrote footnote.el and changed bookmark.el apropos.el autorevert.el calc.el cua-rect.el @@ -932,7 +932,7 @@ and co-wrote longlines.el tango-dark-theme.el tango-theme.el and changed simple.el display.texi xdisp.c files.el frames.texi cus-edit.el files.texi custom.el subr.el text.texi faces.el keyboard.c startup.el package.el misc.texi emacs.texi modes.texi mouse.el - custom.texi image.c window.el and 932 other files + custom.texi image.c window.el and 934 other files Chris Chase: co-wrote idlw-shell.el idlwave.el @@ -1288,7 +1288,7 @@ and co-wrote hideshow.el and changed vc.el configure.ac vc-hg.el vc-git.el src/Makefile.in vc-bzr.el sysdep.c emacs.c process.c vc-cvs.el lisp.h term.c vc-hooks.el xterm.c keyboard.c vc-svn.el xterm.el callproc.c darwin.h - term.el gnu-linux.h and 918 other files + term.el gnu-linux.h and 920 other files Danny Freeman: changed treesit-tests.el treesit.el @@ -1328,7 +1328,7 @@ and co-wrote latin-ltx.el socks.el and changed configure.ac help.el mule-cmds.el fortran.el mule-conf.el xterm.c browse-url.el mule.el coding.c src/Makefile.in european.el fns.c mule-diag.el simple.el wid-edit.el cus-edit.el cus-start.el - files.el keyboard.c byte-opt.el info.el and 772 other files + files.el keyboard.c byte-opt.el info.el and 771 other files Dave Pearson: wrote 5x5.el quickurl.el @@ -1364,7 +1364,7 @@ David De La Harpe Golden: changed files.el mouse.el simple.el fileio.c cus-start.el nsselect.m select.el w32-fns.el x-win.el xterm.c David Edmondson: changed message.el erc.el mml2015.el process.c - gnus-cite.el gnus-cloud.el gnus.texi mm-uu.el mm-view.el net/imap.el + gnus-cite.el gnus-cloud.el gnus.texi imap.el mm-uu.el mm-view.el nnfolder.el nnimap.el nnml.el rcirc.el shr.el Davide Masserut: changed sh-script.el bindings.el Makefile.in basic.texi @@ -1415,7 +1415,7 @@ David J. Biesack: changed antlr-mode.el quickurl.el David J. MacKenzie: changed configure.ac Makefile.in etags.c fakemail.c cvtmail.c movemail.c termcap.c wakeup.c yow.c Makefile avoid.el b2m.c config.in digest-doc.c emacsclient.c emacsserver.c emacstool.c - etags-vmslib.c fortran.el hexl.c isearch.el and 13 other files + etags-vmslib.c fortran.el hexl.c isearch.el and 14 other files David Kågedal: wrote tempo.el and changed sendmail.el xmenu.c @@ -1460,8 +1460,8 @@ and changed gnus-xmas.el David Mosberger-Tang: changed alpha.h unexelf.c cm.h config.in configure.ac cvtmail.c data.c dispnew.c emacsserver.c etags.c - fakemail.c keyboard.c mem-limits.h process.c sorted-doc.c sysdep.c - terminfo.c unexelf1.c yow.c + fakemail.c keyboard.c mem-limits.h process.c profile.c sorted-doc.c + sysdep.c terminfo.c unexelf1.c yow.c David M. Smith: wrote ielm.el and changed imenu.el pgg-def.el xterm.c @@ -1509,10 +1509,10 @@ Debarshi Ray: changed erc-backend.el erc.el Decklin Foster: changed nngateway.el -Deepak Goel: changed idlw-shell.el feedmail.el files.el find-func.el - flymake.el mh-search.el mh-seq.el mh-thread.el mh-xface.el org.el - simple.el vc.el vhdl-mode.el wdired.el README allout.el appt.el - apropos.el artist.el bibtex.el bindings.el and 82 other files +Deepak Goel: changed idlw-shell.el ada-xref.el feedmail.el files.el + find-func.el flymake.el mh-search.el mh-seq.el mh-thread.el mh-xface.el + org.el simple.el vc.el vhdl-mode.el wdired.el README ada-mode.el + allout.el appt.el apropos.el artist.el and 85 other files D. E. Evans: changed basic.texi @@ -1541,7 +1541,7 @@ Denys Duchier: changed pop3.el Denys Nykula: changed TUTORIAL.uk language/cyrillic.el -Derek Atkins: changed net/imap.el pgg-pgp.el +Derek Atkins: changed imap.el pgg-pgp.el Derek L. Davies: changed gud.el @@ -1681,7 +1681,7 @@ Editorconfig Team: wrote editorconfig-conf-mode.el editorconfig-core-handle.el editorconfig-core.el editorconfig-fnmatch.el editorconfig-tools.el editorconfig.el -Ed L. Cashin: changed gnus-sum.el net/imap.el +Ed L. Cashin: changed gnus-sum.el imap.el Ed Swarthout: changed hexl.el textmodes/table.el @@ -1716,9 +1716,8 @@ E. Jay Berkenbilt: changed b2m.c flyspell.el ispell.el unrmail.el Elad Lahav: changed configure.ac -Elias G. B. Perez: changed flymake.el flymake.texi - -Elias G. Perez: changed flymake.el image.c w32term.c w32term.h +Elías Gabriel Pérez: changed flymake.el flymake.texi image.c w32term.c + w32term.h Elias Oltmanns: changed tls.el gnus-agent.el gnus-cite.el gnus-int.el gnus-srvr.el gnus.el nnimap.el @@ -1736,9 +1735,9 @@ Eli Zaretskii: wrote [bidirectional display in xdisp.c] chartab-tests.el coding-tests.el etags-tests.el rxvt.el tty-colors.el and co-wrote help-tests.el and changed xdisp.c display.texi w32.c msdos.c simple.el w32fns.c - files.el fileio.c keyboard.c emacs.c configure.ac text.texi w32term.c + files.el fileio.c keyboard.c configure.ac emacs.c text.texi w32term.c dispnew.c frames.texi files.texi w32proc.c xfaces.c window.c - dispextern.h lisp.h and 1400 other files + dispextern.h lisp.h and 1404 other files Eliza Velasquez: changed server.el simple.el @@ -1762,6 +1761,7 @@ Emilio C. Lopes: changed woman.el cmuscheme.el help.el vc.el advice.el and 58 other files Emmanuel Briot: wrote xml.el +and changed ada-mode.el ada-stmt.el ada-prj.el ada-xref.el Era Eriksson: changed bibtex.el dired.el json.el ses.el ses.texi shell.el tramp.el tramp.texi @@ -1830,10 +1830,10 @@ Eric M. Ludlam: wrote analyze.el analyze/complete.el analyze/debug.el tag-ls.el tag-write.el tag.el test.el and co-wrote db-ebrowse.el srecode/cpp.el util-modes.el and changed c.srt ede.texi info.el rmail.el speedbspec.el cedet.el - ede-autoconf.srt ede-make.srt eieio.texi gud.el - lisp/obsolete/inversion.el sb-dir-minus.xpm sb-dir-plus.xpm sb-dir.xpm - sb-mail.xpm sb-pg-minus.xpm sb-pg-plus.xpm sb-pg.xpm sb-tag-gt.xpm - sb-tag-minus.xpm and 37 other files + ede-autoconf.srt ede-make.srt eieio.texi gud.el sb-dir-minus.xpm + sb-dir-plus.xpm sb-dir.xpm sb-mail.xpm sb-pg-minus.xpm sb-pg-plus.xpm + sb-pg.xpm sb-tag-gt.xpm sb-tag-minus.xpm sb-tag-plus.xpm + and 35 other files Eric Schulte: wrote ob-awk.el ob-calc.el ob-comint.el ob-css.el ob-ditaa.el ob-dot.el ob-emacs-lisp.el ob-eval.el ob-forth.el @@ -1897,8 +1897,8 @@ Espen Skoglund: wrote pascal.el Espen Wiborg: changed utf-7.el -Ethan Bradford: changed ispell.el ange-ftp.el gnus.el gnuspost.el - lisp/obsolete/vt-control.el lpr.el mailalias.el +Ethan Bradford: changed ispell.el ange-ftp.el gnus.el gnuspost.el lpr.el + mailalias.el vt-control.el Ethan Ligon: changed org-docbook.el ox-html.el @@ -2139,8 +2139,7 @@ Gary Oberbrunner: changed eglot.el gud.el Gary Wong: changed termcap.c tparam.c -Gaute B Strokkenes: changed net/imap.el gnus-fun.el mail-source.el - process.c +Gaute B Strokkenes: changed imap.el gnus-fun.el mail-source.el process.c Gautier Ponsinet: changed calendar.texi @@ -2191,7 +2190,7 @@ Gerd Möllmann: wrote authors.el ebrowse.el jit-lock.el tooltip.el and changed xdisp.c xterm.c dispnew.c dispextern.h xfns.c xfaces.c window.c keyboard.c lisp.h faces.el alloc.c buffer.c startup.el xterm.h fns.c term.c configure.ac simple.el frame.c xmenu.c emacs.c - and 621 other files + and 626 other files Gergely Nagy: changed erc.el @@ -2221,7 +2220,7 @@ and changed configure.ac Makefile.in src/Makefile.in calendar.el lisp/Makefile.in diary-lib.el files.el make-dist rmail.el progmodes/f90.el bytecomp.el admin.el misc/Makefile.in simple.el authors.el startup.el emacs.texi lib-src/Makefile.in display.texi - ack.texi subr.el and 1790 other files + ack.texi subr.el and 1796 other files Glynn Clements: wrote gamegrid.el snake.el tetris.el @@ -2705,7 +2704,7 @@ Jason Kim: changed shell.el Jason L. Wright: changed smtpmail.el -Jason Merrill: changed gnus-sum.el add-log.el gnus-salt.el net/imap.el +Jason Merrill: changed gnus-sum.el add-log.el gnus-salt.el imap.el nnfolder.el Jason Riedy: changed org-table.el org.texi @@ -3162,7 +3161,7 @@ Jorge P. De Morais Neto: changed TUTORIAL cl.texi Jose A. Ortega Ruiz: changed doc-view.el misc.texi mixal-mode.el gnus-sum.el imenu.el url-http.el -Jose E. Marchesi: changed gomoku.el simple.el smtpmail.el +Jose E. Marchesi: changed ada-mode.el gomoku.el simple.el smtpmail.el José L. Doménech: changed dired-aux.el @@ -3215,11 +3214,11 @@ and co-wrote help-tests.el keymap-tests.el and changed subr.el desktop.el w32fns.c bs.el faces.el simple.el emacsclient.c files.el server.el help-fns.el xdisp.c org.el w32term.c w32.c buffer.c keyboard.c ido.el image.c window.c eval.c allout.el - and 1222 other files + and 1228 other files Juan Pechiar: changed ob-octave.el -Juergen Kreileder: changed net/imap.el nnimap.el +Juergen Kreileder: changed imap.el nnimap.el Juergen Nickelsen: wrote ws-mode.el @@ -3266,7 +3265,7 @@ Juri Linkov: wrote compose.el emoji.el files-x.el misearch.el and changed isearch.el simple.el info.el replace.el dired.el dired-aux.el minibuffer.el window.el progmodes/grep.el outline.el subr.el vc.el mouse.el diff-mode.el repeat.el files.el image-mode.el menu-bar.el - vc-git.el project.el search.texi and 490 other files + vc-git.el project.el search.texi and 491 other files Jussi Lahdenniemi: changed w32fns.c ms-w32.h msdos.texi w32.c w32.h w32console.c w32heap.c w32inevt.c w32term.h @@ -3296,7 +3295,7 @@ and co-wrote longlines.el tramp-sh.el tramp.el and changed message.el gnus-agent.el gnus-sum.el files.el nnmail.el tramp.texi nntp.el gnus.el simple.el ange-ftp.el dired.el paragraphs.el bindings.el files.texi gnus-art.el gnus-group.el man.el INSTALL - Makefile.in crisp.el fileio.c and 44 other files + Makefile.in crisp.el fileio.c and 45 other files Kailash C. Chowksey: changed HELLO ind-util.el kannada.el knd-util.el lisp/Makefile.in loadup.el @@ -3342,7 +3341,7 @@ and changed simple.el files.el CONTRIBUTE doc-view.el image-mode.el Karl Heuer: changed keyboard.c lisp.h xdisp.c buffer.c xfns.c xterm.c alloc.c files.el frame.c configure.ac window.c data.c minibuf.c editfns.c fns.c process.c Makefile.in fileio.c simple.el keymap.c - indent.c and 445 other files + indent.c and 447 other files Karl Kleinpaste: changed gnus-sum.el gnus-art.el gnus-picon.el gnus-score.el gnus-uu.el gnus-xmas.el gnus.el mm-uu.el mml.el nnmail.el @@ -3372,7 +3371,7 @@ Katsumi Yamaoka: wrote canlock.el and changed gnus-art.el gnus-sum.el message.el mm-decode.el gnus.texi mm-util.el mm-view.el gnus-group.el gnus-util.el gnus-msg.el mml.el shr.el rfc2047.el gnus-start.el gnus.el nntp.el gnus-agent.el nnrss.el - mm-uu.el nnmail.el emacs-mime.texi and 159 other files + mm-uu.el nnmail.el emacs-mime.texi and 158 other files Kaushal Modi: changed dired-aux.el files.el isearch.el apropos.el calc-yank.el custom.texi desktop.el dired.el dired.texi ediff-diff.el @@ -3389,7 +3388,7 @@ Kazuhiro Ito: changed coding.c epg.el japan-util.el uudecode.el flow-fill.el font.c image.c keyboard.c language/japanese.el make-mode.el starttls.el xdisp.c -Kazushi Marukawa: changed filelock.c hexl.c unexalpha.c +Kazushi Marukawa: changed filelock.c hexl.c profile.c unexalpha.c Keiichi Suzuki: changed nntp.el @@ -3509,12 +3508,12 @@ Kim F. Storm: wrote bindat.el cua-base.el cua-gmrk.el cua-rect.el ido.el and changed xdisp.c dispextern.h process.c simple.el window.c keyboard.c xterm.c dispnew.c subr.el w32term.c lisp.h fringe.c display.texi macterm.c alloc.c fns.c xfaces.c keymap.c xfns.c xterm.h .gdbinit - and 248 other files + and 249 other files Kimit Yada: changed copyright.el Kim-Minh Kaplan: changed gnus-picon.el gnus-sum.el gnus-start.el - gnus-win.el gnus-xmas.el gnus.texi message.el net/imap.el nndraft.el + gnus-win.el gnus-xmas.el gnus.texi imap.el message.el nndraft.el nnml.el Kira Bruneau: changed files.el pgtk-win.el @@ -3559,10 +3558,10 @@ Konrad Hinsen: wrote ol-eshell.el and changed ob-python.el Konstantin Kharlamov: changed smerge-mode.el diff-mode.el files.el - alloc.c autorevert.el calc-aent.el calc-ext.el calc-lang.el cc-mode.el - cperl-mode.el css-mode.el cua-rect.el dnd.el ebnf-abn.el ebnf-dtd.el - ebnf-ebx.el emacs-module-tests.el epg.el faces.el gnus-art.el gtkutil.c - and 30 other files + ada-mode.el alloc.c autorevert.el calc-aent.el calc-ext.el calc-lang.el + cc-mode.el cperl-mode.el css-mode.el cua-rect.el dnd.el ebnf-abn.el + ebnf-dtd.el ebnf-ebx.el emacs-module-tests.el epg.el faces.el + gnus-art.el and 31 other files Konstantin Kliakhandler: changed org-agenda.el @@ -3647,7 +3646,7 @@ and co-wrote gnus-kill.el gnus-mh.el gnus-msg.el gnus-score.el and changed subr.el simple.el gnus.texi files.el display.texi process.c help-fns.el text.texi image.c dired.el help.el image.el package.el edebug.el shortdoc.el dired-aux.el gnutls.c minibuffer.el subr-x.el - auth-source.el smtpmail.el and 1063 other files + auth-source.el smtpmail.el and 1061 other files Lars Rasmusson: changed ebrowse.c @@ -3683,11 +3682,11 @@ Lele Gaifax: changed progmodes/python.el TUTORIAL.it python-tests.el flymake-proc.el flymake.texi isearch.el pgtkfns.c xterm.c Lennart Borgman: co-wrote ert-x.el -and changed nxml-mode.el tutorial.el re-builder.el window.el buff-menu.el - emacs-lisp/debug.el emacsclient.c filesets.el flymake.el help-fns.el - isearch.el linum.el lisp-mode.el lisp.el mouse.el progmodes/grep.el - recentf.el remember.el replace.el reveal.el ruby-mode.el - and 5 other files +and changed nxml-mode.el tutorial.el re-builder.el window.el ada-xref.el + buff-menu.el emacs-lisp/debug.el emacsclient.c filesets.el flymake.el + help-fns.el isearch.el linum.el lisp-mode.el lisp.el mouse.el + progmodes/grep.el recentf.el remember.el replace.el reveal.el + and 6 other files Lennart Staflin: changed dired.el diary-ins.el diary-lib.el tq.el xdisp.c @@ -3790,7 +3789,7 @@ Lute Kamstra: changed modes.texi emacs-lisp/debug.el generic-x.el generic.el font-lock.el simple.el subr.el battery.el debugging.texi easy-mmode.el elisp.texi emacs-lisp/generic.el hl-line.el info.el octave.el basic.texi bindings.el calc.el cmdargs.texi diff-mode.el - doclicense.texi and 288 other files + doclicense.texi and 289 other files Lynn Slater: wrote help-macro.el @@ -3952,7 +3951,7 @@ and changed cus-edit.el files.el progmodes/compile.el rmail.el tex-mode.el find-func.el rmailsum.el simple.el cus-dep.el dired.el mule-cmds.el rmailout.el checkdoc.el configure.ac custom.el emacsbug.el gnus.el help-fns.el ls-lisp.el mwheel.el sendmail.el - and 124 other files + and 126 other files Markus Sauermann: changed lisp-mode.el @@ -4001,7 +4000,7 @@ Martin Pohlack: changed iimage.el pc-select.el Martin Rudalics: changed window.el window.c windows.texi frame.c xdisp.c xterm.c frames.texi w32fns.c w32term.c xfns.c frame.el display.texi frame.h help.el cus-start.el buffer.c window.h mouse.el dispnew.c - keyboard.c nsfns.m and 215 other files + keyboard.c nsfns.m and 216 other files Martin Stjernholm: wrote cc-bytecomp.el and co-wrote cc-align.el cc-cmds.el cc-compat.el cc-defs.el cc-engine.el @@ -4058,7 +4057,7 @@ Mats Lidell: changed TUTORIAL.sv european.el gnus-art.el org-element.el Matt Armstrong: changed itree.c buffer-tests.el itree.h buffer.c alloc.c buffer.h display.texi editfns.c filelock-tests.el package.el pdumper.c .clang-format coding.c commands.texi eval.c filelock.c files.el - gnus-topic.el gnus.el lisp-mnt.el lisp.h and 12 other files + gnus-topic.el gnus.el imap.el lisp-mnt.el and 12 other files Matt Beshara: changed js.el nsfns.m @@ -4175,7 +4174,7 @@ and changed tramp.texi tramp-adb.el trampver.el trampver.texi files.el dbusbind.c gitlab-ci.yml files.texi ange-ftp.el file-notify-tests.el dbus.texi Dockerfile.emba autorevert.el tramp-container.el tramp-fish.el kqueue.c os.texi files-x.el shell.el simple.el README - and 329 other files + and 330 other files Michael Ben-Gershon: changed acorn.h configure.ac riscix1-1.h riscix1-2.h unexec.c @@ -4391,7 +4390,7 @@ Miles Bader: wrote button.el face-remap.el image-file.el macroexp.el and changed comint.el faces.el simple.el editfns.c xfaces.c xdisp.c info.el minibuf.c display.texi quick-install-emacs wid-edit.el xterm.c dispextern.h subr.el window.el cus-edit.el diff-mode.el xfns.c - bytecomp.el help.el lisp.h and 271 other files + bytecomp.el help.el lisp.h and 272 other files Milton Wulei: changed gdb-ui.el @@ -4457,7 +4456,7 @@ Nacho Barrientos: changed url-http.el bindat-tests.el bindat.el Nachum Dershowitz: co-wrote cal-hebrew.el Nagy Andras: co-wrote gnus-sieve.el -and changed net/imap.el gnus.el +and changed imap.el gnus.el Nakagawa Makoto: changed ldap.el @@ -4580,7 +4579,7 @@ and changed README authors.el configure.ac sed2v2.inp sequences.texi README.W32 emacs.png HISTORY emacs23.png arc-mode.el cl-extra.el emacs.svg manoj-dark-theme.el Emacs.icns Makefile.in auth-source.el emacs.ico fns.c make-tarball.txt obarray-tests.el obarray.el - and 36 other files + and 37 other files Nicolas Richard: wrote cl-seq-tests.el cmds-tests.el replace-tests.el and changed ffap.el package.el use-package.el byte-run.el help.el @@ -4771,7 +4770,7 @@ and co-wrote cal-dst.el and changed lisp.h configure.ac alloc.c fileio.c process.c editfns.c sysdep.c xdisp.c fns.c image.c data.c emacs.c keyboard.c lread.c xterm.c eval.c gnulib-comp.m4 merge-gnulib callproc.c Makefile.in - buffer.c and 1887 other files + buffer.c and 1892 other files Paul Fisher: changed fns.c @@ -4799,7 +4798,7 @@ Paul Reilly: changed dgux.h lwlib-Xm.c lwlib.c xlwmenu.c configure.ac lwlib/Makefile.in mail/rmailmm.el rmailedit.el rmailkwd.el and 10 other files -Paul Rivier: changed mixal-mode.el reftex-vars.el reftex.el +Paul Rivier: changed ada-mode.el mixal-mode.el reftex-vars.el reftex.el Paul Rubin: changed config.h sun2.h texinfmt.el window.c @@ -4821,7 +4820,7 @@ Pavel Janík: co-wrote eudc-bob.el eudc-export.el eudc-hotlist.el and changed keyboard.c xterm.c COPYING xdisp.c process.c emacs.c lisp.h menu-bar.el ldap.el make-dist xfns.c buffer.c coding.c eval.c fileio.c flyspell.el fns.c indent.c Makefile.in callint.c cus-start.el - and 697 other files + and 702 other files Pavel Kobiakov: wrote flymake-proc.el flymake.el and changed flymake.texi @@ -5177,7 +5176,7 @@ Reiner Steib: wrote gmm-utils.el and changed message.el gnus.texi gnus-art.el gnus-sum.el gnus-group.el gnus.el mml.el gnus-faq.texi mm-util.el gnus-score.el message.texi gnus-msg.el gnus-start.el gnus-util.el spam-report.el mm-uu.el spam.el - mm-decode.el files.el gnus-agent.el nnmail.el and 171 other files + mm-decode.el files.el gnus-agent.el nnmail.el and 170 other files Remek Trzaska: changed gnus-ems.el @@ -5197,9 +5196,9 @@ and changed vhdl-mode.texi Reuben Thomas: changed ispell.el whitespace.el dired-x.el files.el sh-script.el emacsclient-tests.el remember.el README emacsclient.c - misc.texi msdos.c simple.el INSTALL alloc.c arc-mode.el authors.el - config.bat copyright cperl-mode.el dired-x.texi dired.el - and 36 other files + misc.texi msdos.c simple.el INSTALL ada-mode.el ada-xref.el alloc.c + arc-mode.el authors.el config.bat copyright cperl-mode.el + and 38 other files Ricardo Martins: changed eglot.el @@ -5248,7 +5247,7 @@ and co-wrote cc-align.el cc-cmds.el cc-defs.el cc-engine.el cc-langs.el and changed files.el keyboard.c simple.el xterm.c xdisp.c rmail.el fileio.c process.c sysdep.c buffer.c xfns.c window.c subr.el configure.ac startup.el sendmail.el emacs.c Makefile.in editfns.c - info.el dired.el and 1336 other files + info.el dired.el and 1339 other files Richard Ryniker: changed sendmail.el @@ -5283,7 +5282,7 @@ Robert Cochran: changed tab-bar.el bytecomp.el checkdoc.el data.c Robert Fenk: changed desktop.el -Robert Jarzmik: changed ede/linux.el lisp/obsolete/inversion.el +Robert Jarzmik: changed ede/linux.el inversion.el Robert J. Chassell: wrote makeinfo.el page-ext.el texinfo.el texnfo-upd.el @@ -5320,7 +5319,6 @@ Rob Kaut: changed vhdl-mode.el Rob Riepel: wrote tpu-edt.doc tpu-edt.el tpu-extras.el tpu-mapper.el vt-control.el -and changed lisp/obsolete/vt-control.el Roderick Schertler: changed dgux.h dgux4.h gud.el sysdep.c @@ -5382,9 +5380,10 @@ R Primus: changed eglot.el Rüdiger Sonderfeld: wrote inotify-tests.el reftex-tests.el and changed eww.el octave.el shr.el bibtex.el configure.ac - misc/Makefile.in reftex-vars.el vc-git.el TUTORIAL.de autoinsert.el - building.texi bytecomp.el calc-lang.el cc-langs.el dired.texi editfns.c - emacs.c emacs.texi epa.el erc.el eww.texi and 39 other files + misc/Makefile.in reftex-vars.el vc-git.el TUTORIAL.de ada-mode.el + autoinsert.el building.texi bytecomp.el calc-lang.el cc-langs.el + dired.texi editfns.c emacs.c emacs.texi epa.el erc.el + and 40 other files Rudi Schlatte: changed iso-transl.el @@ -5457,7 +5456,7 @@ Sam Steingold: wrote gulp.el midnight.el and changed progmodes/compile.el cl-indent.el simple.el vc-cvs.el vc.el mouse.el vc-hg.el files.el gnus-sum.el tex-mode.el etags.el font-lock.el sgml-mode.el subr.el window.el ange-ftp.el inf-lisp.el - message.el package.el rcirc.el shell.el and 214 other files + message.el package.el rcirc.el shell.el and 216 other files Samuel Bronson: changed custom.el emacsclient.c keyboard.c progmodes/grep.el semantic/format.el unexmacosx.c @@ -5682,11 +5681,10 @@ Simon Josefsson: wrote dig.el dns-mode.el flow-fill.el fringe.el imap.el url-imap.el and co-wrote gnus-sieve.el gssapi.el mml1991.el nnfolder.el nnimap.el nnml.el rot13.el sieve-manage.el -and changed message.el gnus-sum.el net/imap.el gnus-art.el smtpmail.el - pgg-gpg.el pgg.el gnus-agent.el mml2015.el mml.el gnus-group.el - mm-decode.el gnus-msg.el gnus.texi pgg-pgp5.el browse-url.el - gnus-int.el gnus.el hashcash.el mm-view.el password.el - and 100 other files +and changed message.el gnus-sum.el gnus-art.el smtpmail.el pgg-gpg.el + pgg.el gnus-agent.el mml2015.el mml.el gnus-group.el mm-decode.el + gnus-msg.el gnus.texi pgg-pgp5.el browse-url.el gnus-int.el gnus.el + hashcash.el mm-view.el password.el gnus-cache.el and 99 other files Simon Lang: changed building.texi icomplete.el misterioso-theme.el progmodes/grep.el @@ -5771,7 +5769,7 @@ and co-wrote font-lock.el gitmerge.el pcvs.el visual-wrap.el and changed subr.el simple.el cl-macs.el bytecomp.el keyboard.c files.el lisp.h vc.el eval.c xdisp.c alloc.c buffer.c sh-script.el help-fns.el progmodes/compile.el tex-mode.el lread.c keymap.c package.el window.c - edebug.el and 1724 other files + edebug.el and 1726 other files Stefano Facchini: changed gtkutil.c @@ -5787,7 +5785,7 @@ Stefan-W. Hahn: changed org-bibtex.el ps-print.el simple.el subr.el Stefan Wiens: changed gnus-sum.el -Steinar Bang: changed gnus-setup.el net/imap.el +Steinar Bang: changed gnus-setup.el imap.el Štěpán Němec: changed loadhist.el files.el gnus-sum.el loading.texi subr.el INSTALL calc-ext.el checkdoc.el cl.texi comint.el edebug.texi @@ -5831,11 +5829,11 @@ and changed time-stamp.el time-stamp-tests.el mh-e.el mh-utils-tests.el Stephen J. Turnbull: changed ediff-init.el strings.texi subr.el Stephen Leake: wrote elisp-mode-tests.el -and changed elisp-mode.el xref.el eglot.el window.el mode-local.el - project.el CONTRIBUTE vc-mtn.el cedet-global.el ede/generic.el - simple.el autoload.el bytecomp.el cl-generic.el ede/locate.el - files.texi functions.texi package.el progmodes/grep.el windows.texi - INSTALL.REPO and 32 other files +and changed ada-mode.el ada-xref.el elisp-mode.el xref.el eglot.el + window.el mode-local.el project.el CONTRIBUTE ada-prj.el vc-mtn.el + ada-stmt.el cedet-global.el ede/generic.el simple.el autoload.el + bytecomp.el cl-generic.el ede/locate.el files.texi functions.texi + and 36 other files Stephen Pegoraro: changed xterm.c @@ -6036,7 +6034,7 @@ and co-wrote hideshow.el and changed ewoc.el vc.el info.el processes.texi zone.el lisp-mode.el scheme.el text.texi vc-rcs.el display.texi fileio.c files.el vc-git.el TUTORIAL.it bindat.el cc-vars.el configure.ac dcl-mode.el diff-mode.el - dired.el elisp.texi and 167 other files + dired.el elisp.texi and 169 other files Thierry Banel: co-wrote ob-C.el and changed calc-arith.el @@ -6339,6 +6337,9 @@ Ulrich Ölmann: changed misc.texi Ulrik Vieth: wrote meta-mode.el and changed files.el +Umut Tuna Akgül: changed tabulated-list.el cal-julian-tests.el + cl-preloaded.el image-file.el parse-time.el rcirc.el + Ury Marshak: changed nsfns.m Usami Kenta: changed browse-url.el eglot.el htmlfontify.el @@ -6628,8 +6629,7 @@ Yilkal Argaw: changed manoj-dark-theme.el Yoav Marco: changed sqlite-mode.el -Yoichi Nakayama: changed browse-url.el finder.el - lisp/obsolete/mail/rfc2368.el man.el +Yoichi Nakayama: changed browse-url.el finder.el man.el rfc2368.el Yong Lu: changed charset.c coding.c language/greek.el diff --git a/etc/NEWS b/etc/NEWS index 51f481c763c..caeda0c08db 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -176,6 +176,14 @@ will still be on that candidate after "*Completions*" is updated with a new list of completions. The candidate is automatically deselected when the "*Completions*" buffer is hidden. +--- +*** New user option 'crm-prompt' for 'completing-read-multiple'. +This option configures the prompt format of 'completing-read-multiple'. +By default, the prompt indicates to the user that the completion command +accepts a comma-separated list. The prompt format can include the +separator description and the separator string, which are both stored as +text properties of the 'crm-separator' regular expression. + ** Windows +++ @@ -289,7 +297,7 @@ first argument. This is a way for the callers to indicate, for example, the reason or the context why the project is asked for. --- -*** New command 'project-find-matching-file' +*** New command 'project-find-matching-file'. It can be used when switching between projects with similar file trees (such as Git worktrees of the same repository). It supports being invoked standalone or from the 'project-switch-commands' dispatch menu. @@ -445,10 +453,10 @@ to the corresponding position in the old text and vice versa. This allows passing a string with wildcards, or a cons cell where the first element is a list and the rest is a list of files. -*** Bound unused letters in 'image-dired-thumbnail-mode-map' +*** Bound unused letters in 'image-dired-thumbnail-mode-map'. For a more comfortable navigation experience (as in, no modifier keys), -the keys "f", "b", "n", "p", "a" and "e" are now bound to the -same functions as their C- counterparts. +the keys 'f', 'b', 'n', 'p', 'a' and 'e' are now bound to the +same functions as their 'C-' counterparts. ** Browse URL @@ -666,7 +674,7 @@ those commands search in input history only when the point is after the last prompt. +++ -** Mail-util +** Mail Utils *** New user option 'mail-re-regexps'. This contains the list of regular expressions used to match "Re:" and @@ -1153,13 +1161,18 @@ cloning, or prompts for that, too. When the argument is non-nil, the function switches to a buffer visiting the directory into which the repository was cloned. +--- +*** 'C-x v u' ('vc-revert') now works on directories listed in VC Directory. +Reverting a directory means reverting changes to all files inside it. + ** Package +++ *** No longer warn if a package has no footer line. package.el no longer warns for packages without a "footer line", which is the line that usually appears at the very end of an Emacs Lisp file: -;;; FILENAME ends here + + ;;; FILENAME ends here --- *** New optional argument to 'package-autoremove'. @@ -1210,6 +1223,19 @@ runs its body, and removes the current buffer from * New Modes and Packages in Emacs 31.1 +** New major modes based on the tree-sitter library + +*** New major mode 'mhtml-ts-mode'. +An optional major mode based on the tree-sitter library for editing HTML +files. This mode handles indentation, fontification, and commenting for +embedded JavaScript and CSS. + +--- +*** New major mode 'go-work-ts-mode'. +A major mode based on the tree-sitter library for editing "go.work" +files. If tree-sitter is properly set-up by the user, it can be +enabled for files named "go.work". + * Incompatible Lisp Changes in Emacs 31.1 @@ -1254,9 +1280,26 @@ name. Previously, Eshell only did this for MS-Windows systems. To restore the old behavior, you can set 'eshell-pwd-convert-function' to 'identity'. +--- +** The rx 'eval' form now uses the current elisp dialect for evaluation. +Previously, its argument was always evaluated using dynamic binding. + * Lisp Changes in Emacs 31.1 ++++ +** New functions 'plusp' and 'minusp'. +They return non-nil if a number is positive or negative, respectively, +and signal an error if they are given a non-number. The 'cl-lib' +functions 'cl-plusp' and 'cl-minusp' are now aliases for 'plusp' and +'minusp'. + ++++ +** New functions 'oddp' and 'evenp'. +They return non-nil if an integer is odd or even, respectively, and +signal an error if they are given a non-integer. The 'cl-lib' functions +'cl-oddp' and 'cl-evenp' are now aliases for 'oddp' and 'evenp'. + ** Time & Date +++ @@ -1356,6 +1399,24 @@ language symbol. For example, 'cpp' is translated to "C++". A new variable 'treesit-language-display-name-alist' holds the translations of language symbols where that translation is not trivial. +*** New function 'treesit-merge-font-lock-feature-list'. +This function merges two tree-sitter font-lock feature lists. Returns a +new font-lock feature list with no duplicates in the same level. It can +be used to merge font-lock feature lists in a multi-language major mode. + +*** New function 'treesit-replace-font-lock-feature-settings'. +Given two tree-sitter font-lock settings, it replaces the feature in the +second font-lock settings with the same feature in the first font-lock +settings. In a multi-language major mode it is sometimes necessary to +replace features from one of the major modes, with others that are +better suited to the new multilingual context. + +*** New function 'treesit-simple-indent-modify-rules'. +Given two tree-sitter indent rules, it replaces, adds, or prepends rules +in the old rules with new ones, then returns the modified rules. In a +multi-language major mode it is sometimes necessary to modify rules from +one of the major modes to better suit the new multilingual context. + +++ *** New command 'treesit-explore'. This command replaces 'treesit-explore-mode'. It turns on @@ -1372,7 +1433,7 @@ at point to explore. *** New variable 'treesit-aggregated-simple-imenu-settings'. This variable allows major modes to setup Imenu for multiple languages. -*** New function 'treesit-add-simple-indent-rules'. +*** New function 'treesit-simple-indent-add-rules'. This new function makes it easier to customize indent rules for tree-sitter modes. @@ -1528,12 +1589,6 @@ means of the GDI+ library. In addition to ':file FILE' for playing a sound from a file, ':data DATA' can now be used to play a sound from memory. ---- -** New major mode 'go-work-ts-mode'. -A major mode based on the tree-sitter library for editing "go.work" -files. If tree-sitter is properly set-up by the user, it can be -enabled for files named "go.work". - ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/etc/symbol-releases.eld b/etc/symbol-releases.eld index 21bbe3c793c..645ab77972d 100644 --- a/etc/symbol-releases.eld +++ b/etc/symbol-releases.eld @@ -9,6 +9,7 @@ ;; TYPE being `fun' or `var'. ( + ("29.1" fun plistp) ("28.1" fun always) ("26.1" fun when-let*) ("26.1" fun and-let*) diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index f935850b22b..fec95526835 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java @@ -271,20 +271,26 @@ private static class Coordinate } } - EmacsActivity.invalidateFocus (4); - + /* This is just a sanity test and is not reliable since `children' + may be modified between isEmpty and handle destruction. */ if (!children.isEmpty ()) throw new IllegalStateException ("Trying to destroy window with " + "children!"); /* Remove the view from its parent and make it invisible. */ EmacsService.SERVICE.runOnUiThread (new Runnable () { + @Override public void run () { ViewManager parent; EmacsWindowManager manager; + /* Invalidate the focus; this should transfer the input focus + to the next eligible window as this window is no longer + present in parent.children. */ + EmacsActivity.invalidateFocus (4); + if (EmacsActivity.focusedWindow == EmacsWindow.this) EmacsActivity.focusedWindow = null; diff --git a/lisp/align.el b/lisp/align.el index 6467c2b6f57..4263dfe0fa0 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -1076,7 +1076,7 @@ current position." (while (and (> pos (point-min)) (eq (char-before pos) ?\\)) (setq count (1+ count) pos (1- pos))) - (eq (mod count 2) 1)) + (oddp count)) (goto-char (match-beginning (if reverse 1 2))))) result)) diff --git a/lisp/calc/calc-arith.el b/lisp/calc/calc-arith.el index 1bb76c390ba..ac90d6b28ed 100644 --- a/lisp/calc/calc-arith.el +++ b/lisp/calc/calc-arith.el @@ -874,7 +874,7 @@ (defun calcFunc-dint (expr) (let ((types (math-possible-types expr))) (if (= types 1) 1 - (if (= (logand types 1) 0) 0 + (if (evenp types) 0 (math-reject-arg expr 'integerp 'quiet))))) (defun calcFunc-dnumint (expr) diff --git a/lisp/calc/calc-comb.el b/lisp/calc/calc-comb.el index 1ac3347b758..6e2fc08fece 100644 --- a/lisp/calc/calc-comb.el +++ b/lisp/calc/calc-comb.el @@ -826,8 +826,8 @@ '(t)))) ((not (equal n (car math-prime-test-cache))) (cond ((if (consp n) - (= (% (nth 1 n) 2) 0) - (= (% n 2) 0)) + (evenp (nth 1 n)) + (evenp n)) '(nil 2)) ((if (consp n) (= (% (nth 1 n) 5) 0) diff --git a/lisp/calc/calc-ext.el b/lisp/calc/calc-ext.el index 060d352fe66..71f07b2c93a 100644 --- a/lisp/calc/calc-ext.el +++ b/lisp/calc/calc-ext.el @@ -25,7 +25,6 @@ (require 'calc) (require 'calc-macs) -(require 'cl-lib) ;; Declare functions which are defined elsewhere. (declare-function math-clip "calc-bin" (a &optional w)) @@ -2111,7 +2110,7 @@ calc-kill calc-kill-region calc-yank)))) ;;; True if A is an odd integer. [P R R] [Public] (defun math-oddp (a) - (and (integerp a) (cl-oddp a))) + (and (integerp a) (oddp a))) ;;; True if A is an integer. [P x] [Public] (defalias 'math-integerp #'integerp) diff --git a/lisp/calc/calc-funcs.el b/lisp/calc/calc-funcs.el index 28e9c1f30bb..8535e580da7 100644 --- a/lisp/calc/calc-funcs.el +++ b/lisp/calc/calc-funcs.el @@ -867,7 +867,7 @@ (nreverse coefs))) (defun math-bernoulli-number (n) - (if (= (% n 2) 1) + (if (oddp n) (if (= n 1) '(frac -1 2) 0) diff --git a/lisp/calc/calc-keypd.el b/lisp/calc/calc-keypd.el index 2a9c8e75214..ad2b1741181 100644 --- a/lisp/calc/calc-keypd.el +++ b/lisp/calc/calc-keypd.el @@ -411,7 +411,7 @@ (if invhyp (calc-wrapper)) ; clear Inv and Hyp flags (unwind-protect (cond ((or (null cmd) - (= (% row 2) 0)) + (evenp row)) (beep)) ((and (> (minibuffer-depth) 0)) (cond (isstring diff --git a/lisp/calc/calc-math.el b/lisp/calc/calc-math.el index 53e5df30fad..49a64008e0a 100644 --- a/lisp/calc/calc-math.el +++ b/lisp/calc/calc-math.el @@ -402,7 +402,7 @@ If this can't be done, return NIL." (math-div (math-float num-sqrt) den-sqrt)))))) (and (eq (car-safe a) 'float) (if calc-symbolic-mode - (if (= (% (nth 2 a) 2) 0) + (if (evenp (nth 2 a)) (let ((res (cl-isqrt (nth 1 a)))) (if (= (* res res) (nth 1 a)) (math-make-float res (/ (nth 2 a) 2)) @@ -468,7 +468,7 @@ If this can't be done, return NIL." (t (if (null guess) (let ((ldiff (- (math-numdigs (nth 1 a)) 6))) - (or (= (% (+ (nth 2 a) ldiff) 2) 0) (setq ldiff (1+ ldiff))) + (or (evenp (+ (nth 2 a) ldiff)) (setq ldiff (1+ ldiff))) (setq guess (math-make-float (cl-isqrt (math-scale-int (nth 1 a) (- ldiff))) (/ (+ (nth 2 a) ldiff) 2))))) diff --git a/lisp/calc/calc-misc.el b/lisp/calc/calc-misc.el index 62d8f0093b1..564cbfc6537 100644 --- a/lisp/calc/calc-misc.el +++ b/lisp/calc/calc-misc.el @@ -27,7 +27,6 @@ (require 'calc) (require 'calc-macs) -(require 'cl-lib) ;; Declare functions which are defined elsewhere. (declare-function calc-do-keypad "calc-keypd" (&optional full-display interactive)) @@ -736,7 +735,7 @@ loaded and the keystroke automatically re-typed." ;; True if A is an even integer. [P R R] [Public] ;;;###autoload (defun math-evenp (a) - (and (integerp a) (cl-evenp a))) + (and (integerp a) (evenp a))) ;; Compute A / 2, for small or big integer A. [I i] ;; If A is negative, type of truncation is undefined. @@ -899,7 +898,7 @@ loaded and the keystroke automatically re-typed." (defun math-iipow (a n) ; [O O S] (cond ((= n 0) 1) ((= n 1) a) - ((= (% n 2) 0) (math-iipow (math-mul a a) (/ n 2))) + ((evenp n) (math-iipow (math-mul a a) (/ n 2))) (t (math-mul a (math-iipow (math-mul a a) (/ n 2)))))) (defun math-iipow-show (a n) ; [O O S] @@ -907,7 +906,7 @@ loaded and the keystroke automatically re-typed." (let ((val (cond ((= n 0) 1) ((= n 1) a) - ((= (% n 2) 0) (math-iipow-show (math-mul a a) (/ n 2))) + ((evenp n) (math-iipow-show (math-mul a a) (/ n 2))) (t (math-mul a (math-iipow-show (math-mul a a) (/ n 2))))))) (math-working "pow" val) val)) diff --git a/lisp/calc/calc-stat.el b/lisp/calc/calc-stat.el index 57f42645e34..cbf85c51ab4 100644 --- a/lisp/calc/calc-stat.el +++ b/lisp/calc/calc-stat.el @@ -390,7 +390,7 @@ (math-reject-arg (car p) 'anglep)) (setq p (cdr p))) (setq flat (sort flat 'math-lessp)) - (if (= (% len 2) 0) + (if (evenp len) (math-div (math-add (nth (1- hlen) flat) (nth hlen flat)) 2) (nth hlen flat)))))) diff --git a/lisp/calculator.el b/lisp/calculator.el index f7fc0524303..ccb101befe9 100644 --- a/lisp/calculator.el +++ b/lisp/calculator.el @@ -1601,7 +1601,7 @@ To use this, apply a binary operator (evaluate it), then call this." (overflow-error ;; X and Y must be integers, as expt silently returns floating-point ;; infinity on floating-point overflow. - (if (or (natnump x) (zerop (logand y 1))) + (if (or (natnump x) (evenp y)) 1.0e+INF -1.0e+INF)))) diff --git a/lisp/calendar/cal-tex.el b/lisp/calendar/cal-tex.el index c0bb9760810..f5bdfb970cc 100644 --- a/lisp/calendar/cal-tex.el +++ b/lisp/calendar/cal-tex.el @@ -1295,7 +1295,7 @@ Optional EVENT indicates a buffer position to use instead of point." (cal-tex-b-document) (cal-tex-cmd "\\pagestyle" "empty") (dotimes (i n) - (if (zerop (mod i 2)) + (if (evenp i) (insert "\\righthead") (insert "\\lefthead")) (cal-tex-arg @@ -1318,7 +1318,7 @@ Optional EVENT indicates a buffer position to use instead of point." (calendar-extract-year d)))))) (insert "%\n") (dotimes (_jdummy 7) - (if (zerop (mod i 2)) + (if (evenp i) (insert "\\rightday") (insert "\\leftday")) (cal-tex-arg (cal-tex-LaTeXify-string (calendar-day-name date))) @@ -1388,7 +1388,7 @@ Optional EVENT indicates a buffer position to use instead of point." (cal-tex-cmd "\\pagestyle" "empty") (dotimes (i n) (dotimes (j 4) - (let ((even (zerop (% j 2)))) + (let ((even (evenp j))) (insert (if even "\\righthead" "\\lefthead")) diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el index dc6f7345b21..445f37287c3 100644 --- a/lisp/calendar/todo-mode.el +++ b/lisp/calendar/todo-mode.el @@ -55,7 +55,7 @@ ;;; Code: (require 'diary-lib) -(require 'cl-lib) ; For cl-oddp and cl-assert. +(require 'cl-lib) ;; ----------------------------------------------------------------------------- ;;; Setting up todo files, categories, and items @@ -3742,7 +3742,7 @@ Categories mode." (longest (todo-longest-category-name-length categories)) (catlablen (length todo-categories-category-label)) (lc-diff (- longest catlablen))) - (if (and (natnump lc-diff) (cl-oddp lc-diff)) + (if (and (natnump lc-diff) (oddp lc-diff)) (1+ longest) (max longest catlablen)))) @@ -3752,7 +3752,7 @@ The placement of the padding is determined by the value of user option `todo-categories-align'." (let* ((len (todo-adjusted-category-label-length)) (strlen (length str)) - (strlen-odd (eq (logand strlen 1) 1)) + (strlen-odd (oddp strlen)) (padding (max 0 (/ (- len strlen) 2))) (padding-left (cond ((eq todo-categories-align 'left) 0) ((eq todo-categories-align 'center) padding) @@ -3870,7 +3870,7 @@ which is the value of the user option (make-string (1+ (/ (length (car elt)) 2)) 32) ; label (format "%3d" (todo-get-count (cdr elt) cat)) ; count ;; Add an extra space if label length is odd. - (when (cl-oddp (length (car elt))) " "))) + (when (oddp (length (car elt))) " "))) (if archive (list (cons todo-categories-done-label 'done)) (list (cons todo-categories-todo-label 'todo) @@ -3979,7 +3979,7 @@ which is the value of the user option (make-string (1+ (/ (length (car elt)) 2)) 32) (format "%3d" (nth (cdr elt) (todo-total-item-counts))) ;; Add an extra space if label length is odd. - (when (cl-oddp (length (car elt))) " "))) + (when (oddp (length (car elt))) " "))) (if archive (list (cons todo-categories-done-label 2)) (list (cons todo-categories-todo-label 0) diff --git a/lisp/cedet/semantic/bovine/el.el b/lisp/cedet/semantic/bovine/el.el index 436db3c8381..2f1e818e079 100644 --- a/lisp/cedet/semantic/bovine/el.el +++ b/lisp/cedet/semantic/bovine/el.el @@ -765,7 +765,7 @@ In Emacs Lisp this is easily defined by parenthesis bounding." (forward-comment 1) (setq start (point)) (forward-sexp 1) - (if (= (% count 2) 1) + (if (oddp count) (setq lastodd (buffer-substring-no-properties start (point)))) ) diff --git a/lisp/comint.el b/lisp/comint.el index 5d6d02207ad..cece5545bfb 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -1756,7 +1756,7 @@ Go to the history element by the absolute history position HIST-POS." Quotes are single and double." (let ((countsq (comint-how-many-region "\\(^\\|[^\\]\\)'" beg end)) (countdq (comint-how-many-region "\\(^\\|[^\\]\\)\"" beg end))) - (or (= (mod countsq 2) 1) (= (mod countdq 2) 1)))) + (or (oddp countsq) (oddp countdq)))) (defun comint-how-many-region (regexp beg end) "Return number of matches for REGEXP from BEG to END." diff --git a/lisp/dired.el b/lisp/dired.el index 91163186443..e3c686270ac 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2914,7 +2914,7 @@ is controlled by `dired-movement-style'." (dired-move-to-filename) (point))) ;; Up/Down indicates the direction. - (moving-down (if (cl-plusp arg) + (moving-down (if (plusp arg) 1 ; means Down. -1))) ; means Up. ;; Line by line in case we forget to skip empty lines. @@ -2930,7 +2930,7 @@ is controlled by `dired-movement-style'." ;; means infinite loop with no files found. (if (and wrapped (eq old-arg arg)) (setq arg 0) - (goto-char (if (cl-plusp moving-down) + (goto-char (if (plusp moving-down) (point-min) (point-max)))) (setq wrapped t)) diff --git a/lisp/dom.el b/lisp/dom.el index fc032058e9f..4d904c92de9 100644 --- a/lisp/dom.el +++ b/lisp/dom.el @@ -258,31 +258,41 @@ white-space." (insert ")") (insert "\n" (make-string (1+ column) ?\s)))))))) +(define-inline dom--html-boolean-attribute-p (attr) + "Return non-nil if ATTR is an HTML boolean attribute." + (inline-quote + (memq ,attr + ;; Extracted from the HTML Living Standard list of attributes + ;; at . + '( allowfullscreen alpha async autofocus autoplay checked + controls default defer disabled formnovalidate inert ismap + itemscope loop multiple muted nomodule novalidate open + playsinline readonly required reversed selected + shadowrootclonable shadowrootdelegatesfocus + shadowrootserializable)))) + (defun dom-print (dom &optional pretty xml) "Print DOM at point as HTML/XML. If PRETTY, indent the HTML/XML logically. If XML, generate XML instead of HTML." - (let ((column (current-column))) + (let ((column (current-column)) + (indent-tabs-mode nil)) ;; Indent with spaces (insert (format "<%s" (dom-tag dom))) - (let ((attr (dom-attributes dom))) - (dolist (elem attr) - ;; In HTML, these are boolean attributes that should not have - ;; an = value. - (insert (if (and (memq (car elem) - '(async autofocus autoplay checked - contenteditable controls default - defer disabled formNoValidate frameborder - hidden ismap itemscope loop - multiple muted nomodule novalidate open - readonly required reversed - scoped selected typemustmatch)) - (cdr elem) - (not xml)) - (format " %s" (car elem)) - (format " %s=\"%s\"" (car elem) - (url-insert-entities-in-string (cdr elem))))))) + (pcase-dolist (`(,attr . ,value) (dom-attributes dom)) + ;; Don't print attributes without a value. + (when value + (insert + ;; HTML boolean attributes should not have an = value. The + ;; presence of a boolean attribute on an element represents + ;; the true value, and the absence of the attribute + ;; represents the false value. + (if (and (not xml) (dom--html-boolean-attribute-p attr)) + (format " %s" attr) + (format " %s=%S" attr (url-insert-entities-in-string + (format "%s" value))))))) (let* ((children (dom-children dom)) - (non-text nil)) + (non-text nil) + (indent (+ column 2))) (if (null children) (insert " />") (insert ">") @@ -291,16 +301,14 @@ If XML, generate XML instead of HTML." (insert (url-insert-entities-in-string child)) (setq non-text t) (when pretty - (insert "\n" (make-string (+ column 2) ?\s))) + (insert "\n") + (indent-line-to indent)) (dom-print child pretty xml))) ;; If we inserted non-text child nodes, or a text node that ;; ends with a newline, then we indent the end tag. - (when (and pretty - (or (bolp) - non-text)) - (unless (bolp) - (insert "\n")) - (insert (make-string column ?\s))) + (when (and pretty (or (bolp) non-text)) + (or (bolp) (insert "\n")) + (indent-line-to column)) (insert (format "" (dom-tag dom))))))) (provide 'dom) diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el index 10c14e55eae..aa2577300fd 100644 --- a/lisp/elec-pair.el +++ b/lisp/elec-pair.el @@ -558,7 +558,7 @@ The decision is taken by order of preference: ;; Backslash-escaped: no pairing, no skipping. ((save-excursion (goto-char beg) - (not (zerop (% (skip-syntax-backward "\\") 2)))) + (not (evenp (skip-syntax-backward "\\")))) (let ((current-prefix-arg (1- num))) (electric-pair-post-self-insert-function))) ;; Skip self. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index e48cac6c9b1..88e45ddb868 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -3772,7 +3772,7 @@ This assumes the function has the `important-return-value' property." ;; Add missing &optional (or &rest) arguments. (dotimes (_ (- (/ (1+ fmax2) 2) alen)) (byte-compile-push-constant nil))) - ((zerop (logand fmax2 1)) + ((evenp fmax2) (byte-compile-report-error (format "Too many arguments for inlined function %S" form)) (byte-compile-discard (- alen (/ fmax2 2)))) diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el index 6f2f85fc765..2a01501f99e 100644 --- a/lisp/emacs-lisp/chart.el +++ b/lisp/emacs-lisp/chart.el @@ -347,7 +347,7 @@ of the drawing." (odd nil) p1) (while s - (setq odd (= (% (length s) 2) 1)) + (setq odd (oddp (length s))) (setq r (chart-translate-namezone (oref a chart) i)) (if (eq dir 'vertical) (setq p (/ (+ (car r) (cdr r)) 2)) diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el index dd3da9ae8c0..3541e3d0a57 100644 --- a/lisp/emacs-lisp/checkdoc.el +++ b/lisp/emacs-lisp/checkdoc.el @@ -2109,7 +2109,7 @@ The text checked is between START and LIMIT." (goto-char start) (while (and (< (point) p) (re-search-forward "\\\\\"" limit t)) (setq c (1+ c))) - (and (< 0 c) (= (% c 2) 0)))))) + (and (< 0 c) (evenp c)))))) (defun checkdoc-in-abbreviation-p (begin) "Return non-nil if point is at an abbreviation. diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el index 09470457d93..ab06682cf93 100644 --- a/lisp/emacs-lisp/cl-extra.el +++ b/lisp/emacs-lisp/cl-extra.el @@ -392,7 +392,7 @@ With two arguments, return rounding and remainder of their quotient." (res (cl-floor (+ x hy) y))) (if (and (= (car (cdr res)) 0) (= (+ hy hy) y) - (/= (% (car res) 2) 0)) + (oddp (car res))) (list (1- (car res)) hy) (list (car res) (- (car (cdr res)) hy)))) (let ((q (round (/ x y)))) diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index dba01b28325..4a83e9d6a7c 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -270,27 +270,29 @@ so that they are registered at compile-time as well as run-time." (define-obsolete-function-alias 'cl-floatp-safe 'floatp "24.4") -(defsubst cl-plusp (number) - "Return t if NUMBER is positive." - (declare (side-effect-free t)) - (> number 0)) +(defalias 'cl-plusp #'plusp + "Return t if NUMBER is positive. -(defsubst cl-minusp (number) - "Return t if NUMBER is negative." - (declare (side-effect-free t)) - (< number 0)) +This function is considered deprecated in favor of the built-in function +`plusp' that was added in Emacs 31.1.") -(defun cl-oddp (integer) - "Return t if INTEGER is odd." - (declare (side-effect-free t) - (compiler-macro (lambda (_) `(eq (logand ,integer 1) 1)))) - (eq (logand integer 1) 1)) +(defalias 'cl-minusp #'minusp + "Return t if NUMBER is negative. -(defun cl-evenp (integer) - "Return t if INTEGER is even." - (declare (side-effect-free t) - (compiler-macro (lambda (_) `(eq (logand ,integer 1) 0)))) - (eq (logand integer 1) 0)) +This function is considered deprecated in favor of the built-in function +`minusp' that was added in Emacs 31.1.") + +(defalias 'cl-oddp #'oddp + "Return t if INTEGER is odd. + +This function is considered deprecated in favor of the built-in function +`evenp' that was added in Emacs 31.1.") + +(defalias 'cl-evenp #'evenp + "Return t if INTEGER is even. + +This function is considered deprecated in favor of the built-in function +`evenp' that was added in Emacs 31.1.") (defconst cl-digit-char-table (let* ((digits (make-vector 256 nil)) diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index caaffcf19be..e73edbadaf2 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2701,7 +2701,7 @@ Example: (let ((speed (assq (nth 1 (assq 'speed (cdr spec))) '((0 nil) (1 t) (2 t) (3 t)))) (safety (assq (nth 1 (assq 'safety (cdr spec))) - '((0 t) (1 t) (2 t) (3 nil))))) + '((0 t) (1 nil) (2 nil) (3 nil))))) (if speed (setq cl--optimize-speed (car speed) byte-optimize (nth 1 speed))) (if safety (setq cl--optimize-safety (car safety) @@ -3259,7 +3259,7 @@ To see the documentation for a defined struct type, use (declare (side-effect-free t)) ,access-body) forms) - (when (cl-oddp (length desc)) + (when (oddp (length desc)) (push (macroexp-warn-and-return (format-message diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el index a371a8e14de..676252ae126 100644 --- a/lisp/emacs-lisp/crm.el +++ b/lisp/emacs-lisp/crm.el @@ -79,9 +79,25 @@ (define-obsolete-variable-alias 'crm-default-separator 'crm-separator "29.1") -(defvar crm-separator "[ \t]*,[ \t]*" +(defvar crm-separator + (propertize "[ \t]*,[ \t]*" 'separator "," 'description "comma-separated list") "Separator regexp used for separating strings in `completing-read-multiple'. -It should be a regexp that does not match the list of completion candidates.") +It should be a regexp that does not match the list of completion +candidates. The regexp string can carry the text properties `separator' +and `description', which if present `completing-read-multiple' will show +as part of the prompt. See the user option `crm-prompt'.") + +(defcustom crm-prompt "[%d] %p" + "Prompt format for `completing-read-multiple'. +The prompt is formatted by `format-spec' with the keys %d, %s and %p +standing for the separator description, the separator itself and the +original prompt respectively." + :type '(choice (const :tag "Original prompt" "%p") + (const :tag "Description and prompt" "[%d] %p") + (const :tag "Short CRM indication" "[CRM%s] %p") + (string :tag "Custom string")) + :group 'minibuffer + :version "31.1") (defvar-keymap crm-local-completion-map :doc "Local keymap for minibuffer multiple input with completion. @@ -266,8 +282,14 @@ with empty strings removed." (unless (eq require-match t) require-match)) (setq-local crm-completion-table table)) (setq input (read-from-minibuffer - prompt initial-input map - nil hist def inherit-input-method))) + (format-spec + crm-prompt + (let* ((sep (or (get-text-property 0 'separator crm-separator) + (string-replace "[ \t]*" "" crm-separator))) + (desc (or (get-text-property 0 'description crm-separator) + (concat "list separated by " sep)))) + `((?s . ,sep) (?d . ,desc) (?p . ,prompt)))) + initial-input map nil hist def inherit-input-method))) ;; If the user enters empty input, `read-from-minibuffer' ;; returns the empty string, not DEF. (when (and def (string-equal input "")) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index 1fa177b08da..0f029813f80 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -115,10 +115,10 @@ and reference them using the function `class-option'." (cl-check-type superclasses list) (cond ((and (stringp (car options-and-doc)) - (/= 1 (% (length options-and-doc) 2))) + (evenp (length options-and-doc))) (error "Too many arguments to `defclass'")) ((and (symbolp (car options-and-doc)) - (/= 0 (% (length options-and-doc) 2))) + (oddp (length options-and-doc))) (error "Too many arguments to `defclass'"))) (if (stringp (car options-and-doc)) diff --git a/lisp/emacs-lisp/elint.el b/lisp/emacs-lisp/elint.el index 0f5d15be838..5ae8880167d 100644 --- a/lisp/emacs-lisp/elint.el +++ b/lisp/emacs-lisp/elint.el @@ -798,7 +798,7 @@ CODE can be a lambda expression, a macro, or byte-compiled code." (defun elint-check-setq-form (form env) "Lint the setq FORM in ENV." - (or (= (mod (length form) 2) 1) + (or (oddp (length form)) ;; (setq foo) is valid and equivalent to (setq foo nil). (elint-warning "Missing value in setq: %s" form)) (let ((newenv env) @@ -833,7 +833,7 @@ CODE can be a lambda expression, a macro, or byte-compiled code." "Lint the defcustom FORM in ENV." (if (and (> (length form) 3) ;; even no. of keyword/value args ? - (zerop (logand (length form) 1))) + (evenp (length form))) (elint-env-add-global-var (elint-form (nth 2 form) env) (car (cdr form))) (elint-error "Malformed variable declaration: %s" form) diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el index 147787d3d38..0dacec130a0 100644 --- a/lisp/emacs-lisp/ert-x.el +++ b/lisp/emacs-lisp/ert-x.el @@ -260,7 +260,7 @@ structure with the plists in ARGS." (string (let ((begin (point))) (insert x) (set-text-properties begin (point) current-plist))) - (list (unless (zerop (mod (length x) 2)) + (list (unless (evenp (length x)) (error "Odd number of args in plist: %S" x)) (setq current-plist x)))) (buffer-string))) diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 5d1b9f2acbb..28be8666f28 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -576,7 +576,7 @@ Return nil if they are." (defun ert--significant-plist-keys (plist) "Return the keys of PLIST that have non-null values, in order." - (cl-assert (zerop (mod (length plist) 2)) t) + (cl-assert (evenp (length plist)) t) (cl-loop for (key value . rest) on plist by #'cddr unless (or (null value) (memq key accu)) collect key into accu finally (cl-return accu))) @@ -587,8 +587,8 @@ Return nil if they are." Returns nil if they are equivalent, i.e., have the same value for each key, where absent values are treated as nil. The order of key/value pairs in each list does not matter." - (cl-assert (zerop (mod (length a) 2)) t) - (cl-assert (zerop (mod (length b) 2)) t) + (cl-assert (evenp (length a)) t) + (cl-assert (evenp (length b)) t) ;; Normalizing the plists would be another way to do this but it ;; requires a total ordering on all lisp objects (since any object ;; is valid as a text property key). Perhaps defining such an @@ -1419,7 +1419,7 @@ Returns the stats object." (message "%9s %S%s" (ert-string-for-test-result result nil) (ert-test-name test) - (if (cl-plusp + (if (plusp (length (getenv "EMACS_TEST_VERBOSE"))) (ert-reason-for-test-result result) "")))) @@ -1432,7 +1432,7 @@ Returns the stats object." (message "%9s %S%s" (ert-string-for-test-result result nil) (ert-test-name test) - (if (cl-plusp + (if (plusp (length (getenv "EMACS_TEST_VERBOSE"))) (ert-reason-for-test-result result) "")))) @@ -2123,7 +2123,7 @@ non-nil, returns the face for expected results.." (defun ert-face-for-stats (stats) "Return a face that represents STATS." (cond ((ert--stats-aborted-p stats) 'nil) - ((cl-plusp (ert-stats-completed-unexpected stats)) + ((plusp (ert-stats-completed-unexpected stats)) (ert-face-for-test-result nil)) ((eql (ert-stats-completed-expected stats) (ert-stats-total stats)) (ert-face-for-test-result t)) diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index c863857d6ba..dcbdf6942f7 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -294,7 +294,7 @@ The return value is the last VAL in the list. \(fn PLACE VAL PLACE VAL ...)" (declare (debug (&rest [gv-place form]))) - (if (/= (logand (length args) 1) 0) + (if (oddp (length args)) (signal 'wrong-number-of-arguments (list 'setf (length args)))) (if (and args (null (cddr args))) (let ((place (pop args)) diff --git a/lisp/emacs-lisp/helper.el b/lisp/emacs-lisp/helper.el index d8f758d2fe5..8a173219545 100644 --- a/lisp/emacs-lisp/helper.el +++ b/lisp/emacs-lisp/helper.el @@ -80,7 +80,7 @@ (recenter)) ((and (or (eq continue 'backspace) (eq continue ?\177)) - (zerop (% state 2))) + (evenp state)) (scroll-down)) (t (setq continue nil)))))))) diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 4b6f77cc940..897a72d7485 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -435,7 +435,7 @@ Assumes the caller has bound `macroexpand-all-environment'." ;; Malformed code is translated to code that signals an error ;; at run time. (let ((nargs (length args))) - (if (/= (logand nargs 1) 0) + (if (oddp nargs) (macroexp-warn-and-return (format-message "odd number of arguments in `setq' form") `(signal 'wrong-number-of-arguments '(setq ,nargs)) diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index a6a4751f49a..c68b8961ee3 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -370,7 +370,7 @@ undetected, binding variables to arbitrary values, such as nil. (cond (args (let ((arg-length (length args))) - (unless (= 0 (mod arg-length 2)) + (unless (evenp arg-length) (signal 'wrong-number-of-arguments (list 'pcase-setq (+ 2 arg-length))))) (let ((result)) diff --git a/lisp/emacs-lisp/pp.el b/lisp/emacs-lisp/pp.el index e4fa4426c03..6df15b197c8 100644 --- a/lisp/emacs-lisp/pp.el +++ b/lisp/emacs-lisp/pp.el @@ -577,7 +577,7 @@ the bounds of a region containing Lisp code to pretty-print." (insert ")"))) (defun pp--format-definition (sexp indent edebug) - (while (and (cl-plusp indent) + (while (and (plusp indent) sexp) (insert " ") ;; We don't understand all the edebug specs. diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 8fbe35220f1..c512d42cd15 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -1072,7 +1072,7 @@ Return (REGEXP . PRECEDENCE)." "Expand `eval' arguments. Return a new rx form." (unless (and body (null (cdr body))) (error "rx `eval' form takes exactly one argument")) - (eval (car body))) + (eval (car body) lexical-binding)) (defun rx--translate-eval (body) "Translate the `eval' form. Return (REGEXP . PRECEDENCE)." diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index cc9971b232f..23b9b582a9a 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -278,17 +278,17 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), :args (function map) :eval (map-values-apply #'1+ (list '(1 . 2) '(3 . 4)))) (map-filter - :eval (map-filter (lambda (k _) (cl-oddp k)) (list '(1 . 2) '(4 . 6))) - :eval (map-filter (lambda (k v) (cl-evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) + :eval (map-filter (lambda (k _) (oddp k)) (list '(1 . 2) '(4 . 6))) + :eval (map-filter (lambda (k v) (evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) (map-remove - :eval (map-remove (lambda (k _) (cl-oddp k)) (list '(1 . 2) '(4 . 6))) - :eval (map-remove (lambda (k v) (cl-evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) + :eval (map-remove (lambda (k _) (oddp k)) (list '(1 . 2) '(4 . 6))) + :eval (map-remove (lambda (k v) (evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) (map-some - :eval (map-some (lambda (k _) (cl-oddp k)) (list '(1 . 2) '(4 . 6))) - :eval (map-some (lambda (k v) (cl-evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) + :eval (map-some (lambda (k _) (oddp k)) (list '(1 . 2) '(4 . 6))) + :eval (map-some (lambda (k v) (evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) (map-every-p - :eval (map-every-p (lambda (k _) (cl-oddp k)) (list '(1 . 2) '(4 . 6))) - :eval (map-every-p (lambda (k v) (cl-evenp (+ k v))) (list '(1 . 3) '(4 . 6)))) + :eval (map-every-p (lambda (k _) (oddp k)) (list '(1 . 2) '(4 . 6))) + :eval (map-every-p (lambda (k v) (evenp (+ k v))) (list '(1 . 3) '(4 . 6)))) "Combining and changing maps" (map-merge :eval (map-merge 'alist '(1 2 3 4) #s(hash-table data (5 6 7 8))) @@ -1412,16 +1412,16 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), :eval (natnump -1) :eval (natnump 0) :eval (natnump 23)) - (cl-plusp - :eval (cl-plusp 0) - :eval (cl-plusp 1)) - (cl-minusp - :eval (cl-minusp 0) - :eval (cl-minusp -1)) - (cl-oddp - :eval (cl-oddp 3)) - (cl-evenp - :eval (cl-evenp 6)) + (plusp + :eval (plusp 0) + :eval (plusp 1)) + (minusp + :eval (minusp 0) + :eval (minusp -1)) + (oddp + :eval (oddp 3)) + (evenp + :eval (evenp 6)) (bignump :eval (bignump 4) :eval (bignump (expt 2 90))) diff --git a/lisp/emulation/cua-rect.el b/lisp/emulation/cua-rect.el index 27eed91927f..e224d4ce248 100644 --- a/lisp/emulation/cua-rect.el +++ b/lisp/emulation/cua-rect.el @@ -187,7 +187,7 @@ Activates the region if needed. Only lasts until the region is deactivated." ;; t if point is on right side of rectangle. (if (and topbot (= (cua--rectangle-left) (cua--rectangle-right))) (< (cua--rectangle-corner) 2) - (= (mod (cua--rectangle-corner) 2) 1))) + (oddp (cua--rectangle-corner)))) (defun cua--rectangle-column () (if (cua--rectangle-right-side) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 0d72b46360e..e9e643a3df7 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -9735,7 +9735,7 @@ if yet untried." "Format MSG according to ARGS. See also `format-spec'." - (when (eq (logand (length args) 1) 1) ; oddp + (unless (cl-evenp (length args)) (error "Obscure usage of this function appeared")) (let ((entry (erc-retrieve-catalog-entry msg))) (when (not entry) diff --git a/lisp/files-x.el b/lisp/files-x.el index 0e8b99c1e4f..3f57321eb53 100644 --- a/lisp/files-x.el +++ b/lisp/files-x.el @@ -914,7 +914,7 @@ earlier in the `setq-connection-local'. The return value of the \(fn [VARIABLE VALUE]...)" (declare (debug setq)) - (unless (zerop (mod (length pairs) 2)) + (unless (evenp (length pairs)) (error "PAIRS must have an even number of variable/value members")) (let ((set-expr nil) (profile-vars nil)) diff --git a/lisp/files.el b/lisp/files.el index a71d0c5c9d0..bf05939ebeb 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -3469,27 +3469,37 @@ Also applies to `magic-fallback-mode-alist'.") If CASE-INSENSITIVE, the file system of file NAME is case-insensitive." (let (mode) (while name - (setq mode - (if case-insensitive - ;; Filesystem is case-insensitive. - (let ((case-fold-search t)) + (let ((newmode + (if case-insensitive + ;; Filesystem is case-insensitive. + (let ((case-fold-search t)) + (assoc-default name alist 'string-match)) + ;; Filesystem is case-sensitive. + (or + ;; First match case-sensitively. + (let ((case-fold-search nil)) (assoc-default name alist 'string-match)) - ;; Filesystem is case-sensitive. - (or - ;; First match case-sensitively. - (let ((case-fold-search nil)) - (assoc-default name alist 'string-match)) - ;; Fallback to case-insensitive match. - (and auto-mode-case-fold - (let ((case-fold-search t)) - (assoc-default name alist 'string-match)))))) - (if (and mode - (not (functionp mode)) - (consp mode) - (cadr mode)) - (setq mode (car mode) - name (substring name 0 (match-beginning 0))) - (setq name nil))) + ;; Fallback to case-insensitive match. + (and auto-mode-case-fold + (let ((case-fold-search t)) + (assoc-default name alist 'string-match))))))) + (when newmode + (when mode + ;; We had already found a mode but in a (REGEXP MODE t) + ;; entry, so we still have to run MODE. Let's do it now. + ;; FIXME: It's kind of ugly to run the function here. + ;; An alternative could be to return a list of functions and + ;; callers. + (set-auto-mode-0 mode t)) + (setq mode newmode)) + (if (and newmode + (not (functionp newmode)) + (consp newmode) + (cadr newmode)) + ;; It's a (REGEXP MODE t): Keep looking but remember the MODE. + (setq mode (car newmode) + name (substring name 0 (match-beginning 0))) + (setq name nil)))) mode)) (defun set-auto-mode--apply-alist (alist keep-mode-if-same dir-local) diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el index c9f8055fa77..5a55efb3243 100644 --- a/lisp/gnus/gnus-icalendar.el +++ b/lisp/gnus/gnus-icalendar.el @@ -510,7 +510,8 @@ Return nil for non-recurring EVENT." ;; A 0:0 - A .:. -> A 0:0-.:. (default 1) ;; A 0:0 - A+n .:. -> A - A+n .:. ((and start-at-midnight - (cl-plusp start-end-date-diff)) (format "<%s>--<%s %s>" start-date end-date end-time)) + (plusp start-end-date-diff)) + (format "<%s>--<%s %s>" start-date end-date end-time)) ;; default ;; A .:. - A .:. -> A .:.-.:. ;; A .:. - B .:. diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el index 4372fd58669..bf745be0f6e 100644 --- a/lisp/gnus/gnus-uu.el +++ b/lisp/gnus/gnus-uu.el @@ -2098,7 +2098,7 @@ If no file has been included, the user will be asked for a file." (make-string minlen ?-) file-name i parts (make-string - (if (= 0 (% whole-len 2)) (1- minlen) minlen) ?-))) + (if (evenp whole-len) (1- minlen) minlen) ?-))) (goto-char (point-min)) (when (re-search-forward "^Subject: " nil t) diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index dede5520d66..46c3550418f 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -6035,7 +6035,7 @@ In posting styles use `(\"Expires\" (make-expires-date 30))'." (while (search-forward "\"" nil t) (when (prog2 (backward-char) - (zerop (% (skip-chars-backward "\\\\") 2)) + (evenp (skip-chars-backward "\\\\")) (goto-char (match-beginning 0))) (insert "\\")) (forward-char)) diff --git a/lisp/gnus/nndiary.el b/lisp/gnus/nndiary.el index de051745f92..7bc46fa88f8 100644 --- a/lisp/gnus/nndiary.el +++ b/lisp/gnus/nndiary.el @@ -1353,9 +1353,9 @@ all. This may very well take some time.") (max (cond ((= month 2) (if (date-leap-year-p year) 29 28)) ((<= month 7) - (if (zerop (% month 2)) 30 31)) + (if (evenp month) 30 31)) (t - (if (zerop (% month 2)) 31 30)))) + (if (evenp month) 31 30)))) (doms dom-list) (dows dow-list) day days) @@ -1456,9 +1456,9 @@ all. This may very well take some time.") (max (cond ((= month 2) (if (date-leap-year-p year) 29 28)) ((<= month 7) - (if (zerop (% month 2)) 30 31)) + (if (evenp month) 30 31)) (t - (if (zerop (% month 2)) 31 30)))) + (if (evenp month) 31 30)))) (doms dom-list) (dows dow-list) day days) diff --git a/lisp/hexl.el b/lisp/hexl.el index dc2470af46c..f2362a355aa 100644 --- a/lisp/hexl.el +++ b/lisp/hexl.el @@ -1011,7 +1011,7 @@ Embedded whitespace, dashes, and periods in the string are ignored." (let ((chars '())) (let ((len (length str)) (idx 0)) - (if (eq (logand len 1) 1) + (if (oddp len) (let ((num (hexl-hex-string-to-integer (substring str 0 1)))) (setq chars (cons num chars)) (setq idx 1))) diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index a94d9fddade..4d381ba88c6 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -1504,7 +1504,7 @@ If point is on a group name, this function operates on that group." (max (nth 2 form)) (align (nth 3 form)) (elide (nth 4 form))) - (let* ((from-end-p (when (cl-minusp min) + (let* ((from-end-p (when (minusp min) (setq min (- min)) t)) (letbindings nil) @@ -2055,7 +2055,7 @@ the value of point at the beginning of the line for that buffer." element (pcase-let ((`(,sym ,min ,_max ,align) element)) ;; Ignore negative MIN, since the titles are left-aligned. - (when (cl-minusp min) + (when (minusp min) (setq min (- min))) (let* ((name (or (get sym 'ibuffer-column-name) (error "Unknown column %s in ibuffer-formats" sym))) @@ -2080,7 +2080,7 @@ the value of point at the beginning of the line for that buffer." (make-string (length element) ?\s) (pcase-let ((`(,sym ,min ,_max ,align) element)) ;; Ignore negative MIN, since the summaries are left-aligned. - (when (cl-minusp min) + (when (minusp min) (setq min (- min))) (let* ((summary (if (get sym 'ibuffer-column-summarizer) diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 653a7833162..39192a42b6c 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -1564,7 +1564,7 @@ The percentage is in relation to the original size of the image." (interactive (list (read-number "Scale (% of original): " 100 'read-number-history)) image-mode) - (unless (cl-plusp scale) + (unless (plusp scale) (error "Not a positive number: %s" scale)) (setq image-transform-resize (/ scale 100.0)) (image-toggle-display-image)) diff --git a/lisp/info.el b/lisp/info.el index 7a34b43369e..b8ab5b19776 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -4678,7 +4678,6 @@ Advanced commands: ("java" . "ccmode") ("idl" . "ccmode") ("pike" . "ccmode") ("skeleton" . "autotype") ("auto-insert" . "autotype") ("copyright" . "autotype") ("executable" . "autotype") - ("time-stamp" . "autotype") ("tempo" . "autotype") ("hippie-expand" . "autotype") ("cvs" . "pcl-cvs") ("ada" . "ada-mode") "calc" ("calcAlg" . "calc") ("calcDigit" . "calc") ("calcVar" . "calc") diff --git a/lisp/international/emoji.el b/lisp/international/emoji.el index b0a0d66bc9f..55dd97ee6ec 100644 --- a/lisp/international/emoji.el +++ b/lisp/international/emoji.el @@ -222,7 +222,7 @@ the name is not known." (cl-loop for i from 0 for glyph in alist do - (when (and (cl-plusp i) + (when (and (plusp i) (zerop (mod i width))) (insert "\n")) (insert @@ -680,7 +680,7 @@ We prefer the earliest unique letter." ""))) strings))))) nil t))) - (if (cl-plusp (length name)) + (if (plusp (length name)) (let ((glyph (if emoji-alternate-names (cadr (split-string name "\t")) (gethash name emoji--all-bases)))) diff --git a/lisp/isearch.el b/lisp/isearch.el index 1e65a645a1d..c2e41927f08 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -4098,7 +4098,10 @@ This is called when `isearch-update' is invoked (which can cause the search string to change or the window to scroll). It is also used by other Emacs features." (when (and (null executing-kbd-macro) - (sit-for 0) ;make sure (window-start) is credible + ;; This used to read `(sit-for 0)', but that has proved + ;; unreliable when called from within + ;; after-change-functions bound to certain special events. + (redisplay) ;make sure (window-start) is credible (or (not (equal isearch-string isearch-lazy-highlight-last-string)) (not (memq (selected-window) diff --git a/lisp/mail/rfc2047.el b/lisp/mail/rfc2047.el index 38b924851fc..13d1ac320b0 100644 --- a/lisp/mail/rfc2047.el +++ b/lisp/mail/rfc2047.el @@ -1076,7 +1076,7 @@ other than `\"' and `\\' in quoted strings." (while (search-forward "\"" end t) (when (prog2 (backward-char) - (zerop (% (skip-chars-backward "\\\\") 2)) + (evenp (skip-chars-backward "\\\\")) (goto-char (match-beginning 0))) (insert "\\")) (forward-char)) diff --git a/lisp/man.el b/lisp/man.el index a5881f30980..681758cadf5 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -558,9 +558,9 @@ Otherwise, the value is whatever the function (defun Man-shell-file-name () "Return a proper shell file name, respecting remote directories." - (or ; This works also in the local case. + (if (connection-local-p shell-file-name) (connection-local-value shell-file-name) - "/bin/sh")) + "/bin/sh")) (defun Man-header-file-path () "Return the C header file search path that Man should use. diff --git a/lisp/net/gnutls.el b/lisp/net/gnutls.el index 8f00efaccfe..65382a12265 100644 --- a/lisp/net/gnutls.el +++ b/lisp/net/gnutls.el @@ -188,7 +188,7 @@ trust and key files, and priority string." (let* ((parameters (cond ((symbolp parameters) (list :nowait parameters)) - ((not (cl-evenp (length parameters))) + ((not (evenp (length parameters))) (error "Malformed keyword list")) ((consp parameters) parameters) diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index e7ad565dc30..0c1f6181bf9 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -502,7 +502,9 @@ PROPERTIES is a list of file properties (strings)." (mapcar (lambda (property) (cons property (gethash property hash tramp-cache-undefined))) - ,properties))) + ,properties)) + ;; Avoid superfluous debug buffers during host name completion. + (tramp-verbose (if minibuffer-completing-file-name 0 tramp-verbose))) (tramp-message key 7 "Saved %s" values) (unwind-protect (progn ,@body) ;; Reset PROPERTIES. Recompute hash, it could have been flushed. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index f85a371cded..ca890854f85 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -322,8 +322,6 @@ The string is used in `tramp-methods'.") `("plink" (tramp-login-program "plink") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%c") - ;; Since PuTTY 0.82. - ("-legacy-stdio-prompts") ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" @@ -337,8 +335,6 @@ The string is used in `tramp-methods'.") `("plinkx" (tramp-login-program "plink") (tramp-login-args (("-load") ("%h") ("%c") ("-t") ("\"") - ;; Since PuTTY 0.82. - ("-legacy-stdio-prompts") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" tramp-terminal-type @@ -351,8 +347,6 @@ The string is used in `tramp-methods'.") `("pscp" (tramp-login-program "plink") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%c") - ;; Since PuTTY 0.82. - ("-legacy-stdio-prompts") ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" @@ -363,9 +357,7 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") - (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-scp") - ;; Since PuTTY 0.82. - ("-legacy-stdio-prompts") + (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-scp") ("%c") ("-p" "%k") ("-q") ("-r"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) @@ -373,8 +365,6 @@ The string is used in `tramp-methods'.") `("psftp" (tramp-login-program "plink") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%c") - ;; Since PuTTY 0.82. - ("-legacy-stdio-prompts") ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" @@ -385,9 +375,7 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") - (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") - ;; Since PuTTY 0.82. - ("-legacy-stdio-prompts") + (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") ("%c") ("-p" "%k"))) (tramp-copy-keep-date t))) @@ -2497,7 +2485,7 @@ The method used must be an out-of-band method." ;; Compose copy command. (setq options (format-spec - (tramp-ssh-controlmaster-options v) + (tramp-ssh-or-plink-options v) (format-spec-make ?t (tramp-get-connection-property (tramp-get-connection-process v) "temp-file" ""))) @@ -4909,41 +4897,60 @@ Goes through the list `tramp-inline-compress-commands'." (zerop (tramp-call-process vec "ssh" nil nil nil "-G" "-o" option "0.0.0.1")))) -(defun tramp-ssh-controlmaster-options (vec) - "Return the Control* arguments of the local ssh." +(defun tramp-plink-option-exists-p (vec option) + "Check, whether local plink OPTION is applicable." + ;; We don't want to cache it persistently. + (with-tramp-connection-property nil option + ;; "plink" with valid options returns "plink: no valid host name + ;; provided". We xcheck for this error message." + (with-temp-buffer + (tramp-call-process vec "plink" nil t nil option) + (not + (string-match-p + (rx (| (: "plink: unknown option \"" (literal option) "\"" ) + (: "plink: option \"" (literal option) + "\" not available in this tool" ))) + (buffer-string)))))) + +(defun tramp-ssh-or-plink-options (vec) + "Return additional arguments of the local ssh or plink." (cond ;; No options to be computed. - ((or (null tramp-use-connection-share) - (null (assoc "%c" (tramp-get-method-parameter vec 'tramp-login-args)))) - "") + ((null (assoc "%c" (tramp-get-method-parameter vec 'tramp-login-args))) "") - ;; Use plink option. + ;; Use plink options. ((string-match-p (rx "plink" (? ".exe") eol) (tramp-get-method-parameter vec 'tramp-login-program)) - (if (eq tramp-use-connection-share 'suppress) - "-noshare" "-share")) + (concat + (if (eq tramp-use-connection-share 'suppress) + "-noshare" "-share") + ;; Since PuTTY 0.82. + (when (tramp-plink-option-exists-p vec "-legacy-stdio-prompts") + " -legacy-stdio-prompts"))) ;; There is already a value to be used. ((and (eq tramp-use-connection-share t) (stringp tramp-ssh-controlmaster-options)) tramp-ssh-controlmaster-options) - ;; We can't auto-compute the options. - ((ignore-errors - (not (tramp-ssh-option-exists-p vec "ControlMaster=auto"))) - "") + ;; Use ssh options. + (tramp-use-connection-share + ;; We can't auto-compute the options. + (if (ignore-errors + (not (tramp-ssh-option-exists-p vec "ControlMaster=auto"))) + "" - ;; Determine the options. - (t (ignore-errors - ;; ControlMaster and ControlPath options are introduced in OpenSSH 3.9. - (concat - "-o ControlMaster=" - (if (eq tramp-use-connection-share 'suppress) + ;; Determine the options. + (ignore-errors + ;; ControlMaster and ControlPath options are introduced in OpenSSH 3.9. + (concat + "-o ControlMaster=" + (if (eq tramp-use-connection-share 'suppress) "no" "auto") - " -o ControlPath=" - (if (eq tramp-use-connection-share 'suppress) + " -o ControlPath=" + (if (eq tramp-use-connection-share 'suppress) "none" ;; Hashed tokens are introduced in OpenSSH 6.7. On macOS ;; we cannot use an absolute file name, it is too long. @@ -4957,10 +4964,10 @@ Goes through the list `tramp-inline-compress-commands'." (or small-temporary-file-directory tramp-compat-temporary-file-directory)))) - ;; ControlPersist option is introduced in OpenSSH 5.6. + ;; ControlPersist option is introduced in OpenSSH 5.6. (when (and (not (eq tramp-use-connection-share 'suppress)) (tramp-ssh-option-exists-p vec "ControlPersist=no")) - " -o ControlPersist=no")))))) + " -o ControlPersist=no"))))))) (defun tramp-scp-strict-file-name-checking (vec) "Return the strict file name checking argument of the local scp." @@ -5176,9 +5183,9 @@ connection if a previous connection has died for some reason." (let* ((current-host tramp-system-name) (target-alist (tramp-compute-multi-hops vec)) (previous-hop tramp-null-hop) - ;; We will apply `tramp-ssh-controlmaster-options' + ;; We will apply `tramp-ssh-or-plink-options' ;; only for the first hop. - (options (tramp-ssh-controlmaster-options vec)) + (options (tramp-ssh-or-plink-options vec)) (process-connection-type tramp-process-connection-type) (process-adaptive-read-buffering nil) ;; There are unfortunate settings for "cmdproxy" diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index be761a71fa7..a199417b12a 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2534,10 +2534,7 @@ Fall back to normal file name handler if no Tramp file name handler exists." ;; We flush connection properties ;; " process-name" and " process-buffer", ;; because the operations shall be applied - ;; in the main connection process. In order - ;; to avoid superfluous debug buffers during - ;; host name completion, we adapt - ;; `tramp-verbose'. + ;; in the main connection process. ;; If `non-essential' is non-nil, Tramp shall ;; not open a new connection. ;; If Tramp detects that it shouldn't continue @@ -2548,11 +2545,8 @@ Fall back to normal file name handler if no Tramp file name handler exists." ;; In both cases, we try the default handler then. (with-tramp-saved-connection-properties v '(" process-name" " process-buffer") - (let ((tramp-verbose - (if minibuffer-completing-file-name - 0 tramp-verbose))) - (tramp-flush-connection-property v " process-name") - (tramp-flush-connection-property v " process-buffer")) + (tramp-flush-connection-property v " process-name") + (tramp-flush-connection-property v " process-buffer") (setq result (catch 'non-essential (catch 'suppress diff --git a/lisp/obsolete/cl.el b/lisp/obsolete/cl.el index 2ee7e70e4ea..5baa155c592 100644 --- a/lisp/obsolete/cl.el +++ b/lisp/obsolete/cl.el @@ -272,10 +272,6 @@ first svref copy-seq - evenp - oddp - minusp - plusp floatp-safe declaim proclaim diff --git a/lisp/obsolete/thumbs.el b/lisp/obsolete/thumbs.el index 582bb7f0caf..a4f28ce97c5 100644 --- a/lisp/obsolete/thumbs.el +++ b/lisp/obsolete/thumbs.el @@ -628,7 +628,7 @@ ACTION and ARG should be a valid convert command." (defun thumbs-emboss-image (emboss) "Emboss the image with value EMBOSS." (interactive "nEmboss value: ") - (if (or (< emboss 3) (> emboss 31) (zerop (% emboss 2))) + (if (or (< emboss 3) (> emboss 31) (cl-evenp emboss)) (error "Arg must be an odd number between 3 and 31")) (thumbs-modify-image "emboss" (number-to-string emboss))) diff --git a/lisp/org/org-capture.el b/lisp/org/org-capture.el index 0720ad53cc7..d4ae0207c36 100644 --- a/lisp/org/org-capture.el +++ b/lisp/org/org-capture.el @@ -1920,7 +1920,7 @@ placeholder to check." (goto-char (match-beginning 0)) (let ((n (abs (skip-chars-backward "\\\\")))) (delete-char (/ (1+ n) 2)) - (= (% n 2) 1)))) + (cl-oddp n)))) (defun org-capture-expand-embedded-elisp (&optional mark) "Evaluate embedded elisp %(sexp) and replace with the result. diff --git a/lisp/org/org-element-ast.el b/lisp/org/org-element-ast.el index b91cf9fc65c..60ecf34108c 100644 --- a/lisp/org/org-element-ast.el +++ b/lisp/org/org-element-ast.el @@ -731,10 +731,10 @@ a newly created one. When TYPE is `plain-text', CHILDREN must contain a single node - string. Alternatively, TYPE can be a string. When TYPE is nil or `anonymous', PROPS must be nil." - (cl-assert - ;; FIXME: Just use `plistp' from Emacs 29 when available. - (let ((len (proper-list-p props))) - (and len (zerop (% len 2))))) + (cl-assert (if (fboundp 'plistp) ; Emacs 29.1 + (plistp props) + (let ((len (proper-list-p props))) + (and len (cl-evenp len))))) ;; Assign parray. (when (and props (not (stringp type)) (not (eq type 'plain-text))) (let ((node (list 'dummy props))) diff --git a/lisp/org/org-macro.el b/lisp/org/org-macro.el index 66ae4d7af68..500dfbc545d 100644 --- a/lisp/org/org-macro.el +++ b/lisp/org/org-macro.el @@ -329,7 +329,7 @@ Return a list of arguments, as strings. This is the opposite of (lambda (str) (let ((len (length (match-string 1 str)))) (concat (make-string (/ len 2) ?\\) - (if (zerop (mod len 2)) "\000" ",")))) + (if (cl-evenp len) "\000" ",")))) s nil t) "\000")) diff --git a/lisp/org/org-persist.el b/lisp/org/org-persist.el index 104ad86d527..16ac13ae872 100644 --- a/lisp/org/org-persist.el +++ b/lisp/org/org-persist.el @@ -594,7 +594,7 @@ MISC, if non-nil will be appended to the collection. It must be a plist." (unless (and (listp container) (listp (car container))) (setq container (list container))) (setq associated (org-persist--normalize-associated associated)) - (when (and misc (or (not (listp misc)) (= 1 (% (length misc) 2)))) + (when (and misc (or (not (listp misc)) (cl-oddp (length misc)))) (error "org-persist: Not a plist: %S" misc)) (or (org-persist--find-index `( :container ,(org-persist--normalize-container container) diff --git a/lisp/org/ox-odt.el b/lisp/org/ox-odt.el index ba8b4d9d3bb..04c70c5b563 100644 --- a/lisp/org/ox-odt.el +++ b/lisp/org/ox-odt.el @@ -3293,13 +3293,13 @@ styles congruent with the ODF-1.2 specification." (= (1+ r) (car table-dimensions))) "LastRow") ((and (cdr (assq 'use-banding-rows-styles cell-style-selectors)) - (= (% r 2) 1)) "EvenRow") + (cl-oddp r)) "EvenRow") ((and (cdr (assq 'use-banding-rows-styles cell-style-selectors)) - (= (% r 2) 0)) "OddRow") + (cl-evenp r)) "OddRow") ((and (cdr (assq 'use-banding-columns-styles cell-style-selectors)) - (= (% c 2) 1)) "EvenColumn") + (cl-oddp c)) "EvenColumn") ((and (cdr (assq 'use-banding-columns-styles cell-style-selectors)) - (= (% c 2) 0)) "OddColumn") + (cl-evenp c)) "OddColumn") (t "")))) (concat template-name cell-type))))) diff --git a/lisp/org/ox.el b/lisp/org/ox.el index 7f3f66a6f26..a2a21a72c42 100644 --- a/lisp/org/ox.el +++ b/lisp/org/ox.el @@ -7287,14 +7287,14 @@ back to standard interface." (lambda (sub-entry) (cl-incf index) (format - (if (zerop (mod index 2)) " [%s] %-26s" + (if (cl-evenp index) " [%s] %-26s" "[%s] %s\n") (funcall fontify-key (char-to-string (car sub-entry)) top-key) (nth 1 sub-entry))) sub-menu "") - (when (zerop (mod index 2)) "\n")))))))) + (when (cl-evenp index) "\n")))))))) entries "")) ;; Publishing menu is hard-coded. (format "\n[%s] Publish diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el index 3c5a3601927..e7638ef0f59 100644 --- a/lisp/play/5x5.el +++ b/lisp/play/5x5.el @@ -312,7 +312,7 @@ Quit current game \\[5x5-quit-game]" (forward-char (+ 1 (/ (1+ 5x5-x-scale) 2))) (dotimes (x 5x5-grid-size) (when (5x5-cell solution-grid y x) - (if (= 0 (mod 5x5-x-scale 2)) + (if (evenp 5x5-x-scale) (progn (insert "()") (delete-region (point) (+ (point) 2)) diff --git a/lisp/play/gamegrid.el b/lisp/play/gamegrid.el index 328b474f0eb..1be77e2c9a9 100644 --- a/lisp/play/gamegrid.el +++ b/lisp/play/gamegrid.el @@ -205,7 +205,7 @@ static unsigned char gamegrid_bits[] = { (make-list (/ center-pixel-count 2) "01") (list right-border))))) (dotimes (row center-pixel-count) - (gamegrid-insert-xbm-bits (if (eq (logand row 1) 1) odd-line even-line)) + (gamegrid-insert-xbm-bits (if (oddp row) odd-line even-line)) (insert ", \n"))) (dotimes (row border-pixel-count) diff --git a/lisp/play/gametree.el b/lisp/play/gametree.el index c0d43944e67..8ffddfc7275 100644 --- a/lisp/play/gametree.el +++ b/lisp/play/gametree.el @@ -347,7 +347,7 @@ Subnodes which have been manually scored are honored." ;; be either a leaf child, or a subheading. (let ((running gametree-default-score) (minmax - (if (= 0 (mod (gametree-current-branch-ply) 2)) + (if (evenp (gametree-current-branch-ply)) 'max 'min))) (while (and (not (eobp)) (= 0 (gametree-current-branch-depth))) ;handle leaves @@ -395,7 +395,7 @@ depth AT-DEPTH or smaller is found." (gametree-current-branch-ply))))) (goto-char (1- (point))) (insert "\n") - (insert (format (if (= 0 (mod starting-plies 2)) + (insert (format (if (evenp starting-plies) gametree-full-ply-format gametree-half-ply-format) (/ starting-plies 2)))))) @@ -450,7 +450,7 @@ only work of Black's moves are explicitly numbered, for instance gametree-full-ply-regexp "\\|" gametree-half-ply-regexp "\\)"))) (progn - (insert (format (if (= 0 (mod (gametree-looking-at-ply) 2)) + (insert (format (if (evenp (gametree-looking-at-ply)) gametree-full-ply-format gametree-half-ply-format) (/ (gametree-looking-at-ply) 2))) diff --git a/lisp/play/hanoi.el b/lisp/play/hanoi.el index 1a4b6dbeb11..8bc8d77108b 100644 --- a/lisp/play/hanoi.el +++ b/lisp/play/hanoi.el @@ -266,7 +266,7 @@ BITS must be of length nrings. Start at START-TIME." (make-string (1- radius) (if vert ?\- ?\|)) (if vert ">" "v")) for face = - (if (eq (logand n 1) 1) ; oddp would require cl at runtime + (if (oddp n) hanoi-odd-ring-face hanoi-even-ring-face) do (hanoi-put-face 0 (length str) face str) collect (cons str diameter))) diff --git a/lisp/play/zone.el b/lisp/play/zone.el index b294dd6af67..39a33f1e2a0 100644 --- a/lisp/play/zone.el +++ b/lisp/play/zone.el @@ -454,7 +454,7 @@ run a specific program. The program must be a member of (dotimes (i 20) (goto-char pos) (delete-char 1) - (insert (if (= 0 (% i 2)) hmm c-string)) + (insert (if (evenp i) hmm c-string)) (zone-park/sit-for wbeg (setq wait (* wait 0.8)))) (delete-char -1) (insert c-string))) diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index e1ec4880058..e75cfd85c5f 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -3825,7 +3825,7 @@ modify syntax-type text property if the situation is too hard." (char-after (- (point) 2))) (save-excursion (forward-char -2) - (= 0 (% (skip-chars-backward "\\\\") 2))) + (cl-evenp (skip-chars-backward "\\\\"))) (forward-char -1))) ;; Now we are after the first part. (and is-2arg ; Have trailing part @@ -5164,7 +5164,7 @@ recursive calls in starting lines of here-documents." (or ; Should work with delim = \ (not (eq (preceding-char) ?\\ )) ;; XXXX Double \\ is needed with 19.33 - (= (% (skip-chars-backward "\\\\") 2) 0)) + (cl-evenp (skip-chars-backward "\\\\"))) (looking-at (cond ((eq (char-after b) ?\] ) diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el index f3b2d8bb4a4..0147707f80d 100644 --- a/lisp/progmodes/ebnf2ps.el +++ b/lisp/progmodes/ebnf2ps.el @@ -5947,7 +5947,7 @@ killed after process termination." (defun ebnf-end-of-string () (let ((n 1)) - (while (> (logand n 1) 0) + (while (oddp n) (skip-chars-forward "^\"" ebnf-limit) (setq n (- (skip-chars-backward "\\\\"))) (goto-char (+ (point) n 1)))) diff --git a/lisp/progmodes/ebrowse.el b/lisp/progmodes/ebrowse.el index a24c9204b2f..9805a2bf04a 100644 --- a/lisp/progmodes/ebrowse.el +++ b/lisp/progmodes/ebrowse.el @@ -1334,7 +1334,7 @@ Pop to member buffer if no prefix ARG, to tree buffer otherwise." "Indentation" (int-to-string ebrowse--indentation)) nil nil ebrowse--indentation)))) - (when (cl-plusp width) + (when (plusp width) (setq-local ebrowse--indentation width) (ebrowse-redraw-tree)))) @@ -2168,7 +2168,7 @@ The new width is read from the minibuffer." ebrowse--decl-column ebrowse--column-width)) "): "))))) - (when (cl-plusp width) + (when (plusp width) (if ebrowse--long-display-flag (setq ebrowse--decl-column width) (setq ebrowse--column-width width)) @@ -2209,11 +2209,11 @@ make one." ebrowse--accessor #'eql))) (setf ebrowse--accessor - (cond ((cl-plusp incr) + (cond ((plusp incr) (or (nth (1+ index) ebrowse-member-list-accessors) (cl-first ebrowse-member-list-accessors))) - ((cl-minusp incr) + ((minusp incr) (or (and (>= (cl-decf index) 0) (nth index ebrowse-member-list-accessors)) @@ -2693,7 +2693,7 @@ TREE is the class tree in which the members are found." (when (>= i ebrowse--n-columns) (setf i 0) (insert "\n"))))) - (when (cl-plusp i) + (when (plusp i) (insert "\n")) (goto-char (point-min)))) @@ -2863,7 +2863,7 @@ Prefix arg INC specifies which one." (setq index (+ inc (seq-position containing-list ebrowse--displayed-class #'eql))) - (cond ((cl-minusp index) (message "No previous class")) + (cond ((minusp index) (message "No previous class")) ((null (nth index containing-list)) (message "No next class"))) (setq index (max 0 (min index (1- (length containing-list))))) (setq cls (nth index containing-list)) @@ -3729,7 +3729,7 @@ Positions in buffers that have no file names are not saved." (let ((too-much (- (length ebrowse-position-stack) ebrowse-max-positions))) ;; Do not let the stack grow to infinity. - (when (cl-plusp too-much) + (when (plusp too-much) (setq ebrowse-position-stack (butlast ebrowse-position-stack too-much))) ;; Push the position. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index afa7d7b7e54..bd28174e7da 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1259,7 +1259,7 @@ SERVER." (progn (setf (eglot--shutdown-requested server) t) (eglot--request server :shutdown eglot--{} :timeout (or timeout 1.5)) - (jsonrpc-notify server :exit nil)) + (jsonrpc-notify server :exit eglot--{})) ;; Now ask jsonrpc.el to shut down the server. (jsonrpc-shutdown server (not preserve-buffers)) (unless preserve-buffers (kill-buffer (jsonrpc-events-buffer server))))) diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index d61cf4684f9..64813370e9c 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -2008,7 +2008,7 @@ ARGS is the argument list of function SYM." (and (string-match-p "\\.\\.\\.\\'" (substring args 1 (1- (length args)))) (= (length (remove "..." args-lst)) 2) - (> index 1) (eq (logand index 1) 1))) + (> index 1) (oddp index))) (setq index 0)) (t (setq index (1- index)))))) diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el index 7ced54170ff..3cca55be3a7 100644 --- a/lisp/progmodes/gud.el +++ b/lisp/progmodes/gud.el @@ -919,7 +919,7 @@ CONTEXT is the text before COMMAND on the line." (while (string-match "\\([^'\\]\\|\\\\'\\)*'" str pos) (setq count (1+ count) pos (match-end 0))) - (and (= (mod count 2) 1) + (and (oddp count) (setq complete-list (list (concat str "'")))))) complete-list) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 3168395acf1..f2acf9f40d6 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3920,6 +3920,44 @@ See `treesit-thing-settings' for more information.") (defvar js--treesit-jsdoc-beginning-regexp (rx bos "/**") "Regular expression matching the beginning of a jsdoc block comment.") +(defvar js--treesit-thing-settings + `((javascript + (sexp ,(js--regexp-opt-symbol js--treesit-sexp-nodes)) + (list ,(js--regexp-opt-symbol js--treesit-list-nodes)) + (sentence ,(js--regexp-opt-symbol js--treesit-sentence-nodes)) + (text ,(js--regexp-opt-symbol '("comment" + "string_fragment"))))) + "Settings for `treesit-thing-settings'.") + +(defvar js--treesit-font-lock-feature-list + '(( comment document definition) + ( keyword string) + ( assignment constant escape-sequence jsx number + pattern string-interpolation) + ( bracket delimiter function operator property)) + "Settings for `treesit-font-lock-feature-list'.") + +(defvar js--treesit-simple-imenu-settings + `(("Function" "\\`function_declaration\\'" nil nil) + ("Variable" "\\`lexical_declaration\\'" + js--treesit-valid-imenu-entry nil) + ("Class" ,(rx bos (or "class_declaration" + "method_definition") + eos) + nil nil)) + "Settings for `treesit-simple-imenu'.") + +(defvar js--treesit-defun-type-regexp + (rx (or "class_declaration" + "method_definition" + "function_declaration" + "lexical_declaration")) + "Settings for `treesit-defun-type-regexp'.") + +(defvar js--treesit-jsdoc-comment-regexp + (rx (or "comment" "line_comment" "block_comment" "description")) + "Regexp for `c-ts-common--comment-regexp'.") + ;;;###autoload (define-derived-mode js-ts-mode js-base-mode "JavaScript" "Major mode for editing JavaScript. @@ -3951,29 +3989,15 @@ See `treesit-thing-settings' for more information.") ;; Indent. (setq-local treesit-simple-indent-rules js--treesit-indent-rules) ;; Navigation. - (setq-local treesit-defun-type-regexp - (rx (or "class_declaration" - "method_definition" - "function_declaration" - "lexical_declaration"))) + (setq-local treesit-defun-type-regexp js--treesit-defun-type-regexp) + (setq-local treesit-defun-name-function #'js--treesit-defun-name) - (setq-local treesit-thing-settings - `((javascript - (sexp ,(js--regexp-opt-symbol js--treesit-sexp-nodes)) - (list ,(js--regexp-opt-symbol js--treesit-list-nodes)) - (sentence ,(js--regexp-opt-symbol js--treesit-sentence-nodes)) - (text ,(js--regexp-opt-symbol '("comment" - "string_fragment")))))) + (setq-local treesit-thing-settings js--treesit-thing-settings) ;; Fontification. (setq-local treesit-font-lock-settings js--treesit-font-lock-settings) - (setq-local treesit-font-lock-feature-list - '(( comment document definition) - ( keyword string) - ( assignment constant escape-sequence jsx number - pattern string-interpolation) - ( bracket delimiter function operator property))) + (setq-local treesit-font-lock-feature-list js--treesit-font-lock-feature-list) (when (treesit-ready-p 'jsdoc t) (setq-local treesit-range-settings @@ -3983,17 +4007,11 @@ See `treesit-thing-settings' for more information.") :local t `(((comment) @capture (:match ,js--treesit-jsdoc-beginning-regexp @capture))))) - (setq c-ts-common--comment-regexp (rx (or "comment" "line_comment" "block_comment" "description")))) + (setq c-ts-common--comment-regexp js--treesit-jsdoc-comment-regexp)) ;; Imenu - (setq-local treesit-simple-imenu-settings - `(("Function" "\\`function_declaration\\'" nil nil) - ("Variable" "\\`lexical_declaration\\'" - js--treesit-valid-imenu-entry nil) - ("Class" ,(rx bos (or "class_declaration" - "method_definition") - eos) - nil nil))) + (setq-local treesit-simple-imenu-settings js--treesit-simple-imenu-settings) + (treesit-major-mode-setup) (add-to-list 'auto-mode-alist diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el index cdd7765bd7c..77724e04f11 100644 --- a/lisp/progmodes/prog-mode.el +++ b/lisp/progmodes/prog-mode.el @@ -144,6 +144,8 @@ instead." (end (progn (forward-sexp 1) (point)))) (indent-region start end nil)))) +(declare-function treesit-node-at "treesit.c") + (defun prog-fill-reindent-defun (&optional argument) "Refill or reindent the paragraph or defun that contains point. diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 8a99ff0434d..a42e2b2a28a 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -2328,8 +2328,11 @@ of the statement." (setq last-string-end (or (if (eq t (nth 3 (syntax-ppss))) - (re-search-forward - (rx (syntax string-delimiter)) nil t) + (cl-loop + while (re-search-forward + (rx (or "\"\"\"" "'''")) nil t) + unless (python-syntax-context 'string) + return (point)) (ignore-error scan-error (goto-char string-start) (python-nav--lisp-forward-sexp) diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 0d5df5b1dc2..210c8efb6fc 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -1816,8 +1816,7 @@ With ARG, do it many times. Negative ARG means move forward." ((looking-at "\\s\"\\|\\\\\\S_") (let ((c (char-to-string (char-before (match-end 0))))) (while (and (search-backward c) - (eq (logand (skip-chars-backward "\\\\") 1) - 1)))) + (oddp (skip-chars-backward "\\\\"))))) nil) ((looking-at "\\s.\\|\\s\\") (if (ruby-special-char-p) (forward-char -1))) diff --git a/lisp/ps-print.el b/lisp/ps-print.el index c1258db2c54..ba0d543bbcc 100644 --- a/lisp/ps-print.el +++ b/lisp/ps-print.el @@ -4605,21 +4605,19 @@ page-height == ((floor print-height ((th + ls) * zh)) * ((th + ls) * zh)) - th (t nil)) (cond ((eq ps-even-or-odd-pages 'even-page) - (= (logand ps-page-postscript 1) 0)) + (evenp ps-page-postscript)) ((eq ps-even-or-odd-pages 'odd-page) - (= (logand ps-page-postscript 1) 1)) - (t) - )))) + (oddp ps-page-postscript)) + (t))))) (defsubst ps-print-sheet-p () (setq ps-print-page-p (cond ((eq ps-even-or-odd-pages 'even-sheet) - (= (logand ps-page-sheet 1) 0)) + (evenp ps-page-sheet)) ((eq ps-even-or-odd-pages 'odd-sheet) - (= (logand ps-page-sheet 1) 1)) - (t) - ))) + (oddp ps-page-sheet)) + (t)))) (defun ps-output (&rest args) @@ -6462,7 +6460,7 @@ If FACE is not a valid face name, use default face." (replace-match (format "/Lines %d def\n/PageCount %d def" total-lines total-pages) t))))) ;; Set dummy page - (and ps-spool-duplex (= (mod ps-page-order 2) 1) + (and ps-spool-duplex (oddp ps-page-order) (let ((ps-n-up-printing 0)) (ps-header-sheet) (ps-output "/PrintHeader false def\n/ColumnIndex 0 def\n" diff --git a/lisp/replace.el b/lisp/replace.el index 3bd803ce347..b1b417b226f 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -2815,6 +2815,8 @@ and END." (<= end (cdr bounds)))) region-bounds))))) +(defvar overriding-text-conversion-style) + (defun perform-replace (from-string replacements query-flag regexp-flag delimited-flag &optional repeat-count map start end backward region-noncontiguous-p) @@ -2877,10 +2879,13 @@ characters." (limit nil) (region-filter nil) + ;; Disable text conversion during the replacement operation. + (old-text-conversion-style overriding-text-conversion-style) + overriding-text-conversion-style + ;; Data for the next match. If a cons, it has the same format as ;; (match-data); otherwise it is t if a match is possible at point. (match-again t) - (message (if query-flag (apply #'propertize @@ -2935,6 +2940,10 @@ characters." (push-mark) (undo-boundary) + (when query-flag + (setq overriding-text-conversion-style nil) + (when (fboundp 'set-text-conversion-style) + (set-text-conversion-style text-conversion-style))) (unwind-protect ;; Loop finding occurrences that perhaps should be replaced. (while (and keep-going @@ -3352,7 +3361,13 @@ characters." last-was-act-and-show nil)))))) (replace-dehighlight) (when region-filter - (remove-function isearch-filter-predicate region-filter))) + (remove-function isearch-filter-predicate region-filter)) + (when query-flag + ;; Resume text conversion. + (setq overriding-text-conversion-style + old-text-conversion-style) + (when (fboundp 'set-text-conversion-style) + (set-text-conversion-style text-conversion-style)))) (or unread-command-events (message (ngettext "Replaced %d occurrence%s" "Replaced %d occurrences%s" diff --git a/lisp/ses.el b/lisp/ses.el index 88e83ae160b..d23cefc53f4 100644 --- a/lisp/ses.el +++ b/lisp/ses.el @@ -4105,7 +4105,7 @@ printer otherwise." value ; Too large for field, anyway. (setq half (make-string (/ width 2) fill)) (concat half value half - (if (> (% width 2) 0) (char-to-string fill)))))) + (if (oddp width) (char-to-string fill)))))) (defun ses-center-span (value &optional fill printer) "Print VALUE, centered within the span that starts in the current column diff --git a/lisp/subr.el b/lisp/subr.el index 77e909d1bf6..7fdcf6731e7 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -550,6 +550,34 @@ was called." (compiler-macro (lambda (_) `(= 0 ,number)))) (= 0 number)) +(defun plusp (number) + "Return t if NUMBER is positive." + (declare (ftype (function (number) boolean)) + (side-effect-free t) + (compiler-macro (lambda (_) `(> ,number 0)))) + (> number 0)) + +(defun minusp (number) + "Return t if NUMBER is negative." + (declare (ftype (function (number) boolean)) + (side-effect-free t) + (compiler-macro (lambda (_) `(< ,number 0)))) + (< number 0)) + +(defun oddp (integer) + "Return t if INTEGER is odd." + (declare (ftype (function (integer) boolean)) + (side-effect-free t) + (compiler-macro (lambda (_) `(eq (logand ,integer 1) 1)))) + (eq (logand integer 1) 1)) + +(defun evenp (integer) + "Return t if INTEGER is even." + (declare (ftype (function (integer) boolean)) + (side-effect-free t) + (compiler-macro (lambda (_) `(eq (logand ,integer 1) 0)))) + (eq (logand integer 1) 0)) + (defun fixnump (object) "Return t if OBJECT is a fixnum." (declare (ftype (function (t) boolean)) @@ -580,7 +608,7 @@ treatment of negative COUNT provided by this function." (format-message "avoid `lsh'; use `ash' instead") form '(suspicious lsh) t form))) (side-effect-free t)) - (when (and (< value 0) (< count 0)) + (when (and (minusp value) (minusp count)) (when (< value most-negative-fixnum) (signal 'args-out-of-range (list value count))) (setq value (logand (ash value -1) most-positive-fixnum)) @@ -804,7 +832,7 @@ If N is omitted or nil, remove the last element." (or n (setq n 1)) (and (< n m) (progn - (if (> n 0) (setcdr (nthcdr (- (1- m) n) list) nil)) + (if (plusp n) (setcdr (nthcdr (- (1- m) n) list) nil)) list)))) (defun delete-dups (list) @@ -877,7 +905,7 @@ of course, also replace TO with a slightly larger value (or inc (setq inc 1)) (when (zerop inc) (error "The increment can not be zero")) (let (seq (n 0) (next from)) - (if (> inc 0) + (if (plusp inc) (while (<= next to) (setq seq (cons next seq) n (1+ n) @@ -2535,7 +2563,7 @@ HISTORY-VAR cannot refer to a lexical variable." (when (and (listp history) (or keep-all (not (stringp newelt)) - (> (length newelt) 0)) + (plusp (length newelt))) (or keep-all (not (equal (car history) newelt)))) (if history-delete-duplicates @@ -3757,7 +3785,7 @@ There is no need to explicitly add `help-char' to CHARS; (set-text-conversion-style text-conversion-style)) (read-from-minibuffer prompt nil map nil (or history t)))) (char - (if (> (length result) 0) + (if (plusp (length result)) ;; We have a string (with one character), so return the first one. (elt result 0) ;; The default value is RET. @@ -5703,7 +5731,7 @@ Modifies the match data; use `save-match-data' if necessary." (setq this (substring this 0 tem))))) ;; Trimming could make it empty; check again. - (when (or keep-nulls (> (length this) 0)) + (when (or keep-nulls (plusp (length this))) (push this list))))))) (while (and (string-match rexp string @@ -5780,7 +5808,7 @@ Unless optional argument INPLACE is non-nil, return a new string." res) (let ((i (length string)) (newstr (if inplace string (copy-sequence string)))) - (while (> i 0) + (while (plusp i) (setq i (1- i)) (if (eq (aref newstr i) fromchar) (aset newstr i tochar))) @@ -6253,7 +6281,7 @@ backwards ARG times if negative." (interactive "^p") (if (natnump arg) (re-search-forward "[ \t]+\\|\n" nil 'move arg) - (while (< arg 0) + (while (minusp arg) (if (re-search-backward "[ \t]+\\|\n" nil 'move) (or (eq (char-after (match-beginning 0)) ?\n) (skip-chars-backward " \t"))) @@ -6270,7 +6298,7 @@ backwards ARG times if negative." (interactive "^p") (if (natnump arg) (re-search-forward "\\(\\sw\\|\\s_\\)+" nil 'move arg) - (while (< arg 0) + (while (minusp arg) (if (re-search-backward "\\(\\sw\\|\\s_\\)+" nil 'move) (skip-syntax-backward "w_")) (setq arg (1+ arg))))) @@ -6283,11 +6311,11 @@ With prefix argument ARG, do it ARG times if positive, or move backwards ARG times if negative." (interactive "^p") (or arg (setq arg 1)) - (while (< arg 0) + (while (minusp arg) (skip-syntax-backward (char-to-string (char-syntax (char-before)))) (setq arg (1+ arg))) - (while (> arg 0) + (while (plusp arg) (skip-syntax-forward (char-to-string (char-syntax (char-after)))) (setq arg (1- arg)))) @@ -6839,7 +6867,7 @@ NEW-MESSAGE, if non-nil, sets a new message for the reporter." (if suffix (aset parameters 6 suffix) (setq suffix (or (aref parameters 6) ""))) - (if (> percentage 0) + (if (plusp percentage) (message "%s%d%% %s" text percentage suffix) (message "%s %s" text suffix))))) ;; Pulsing indicator @@ -7070,9 +7098,9 @@ turn is higher than (1 -2), which is higher than (1 -3)." ;; l1 null and l2 null ==> l1 length = l2 length ((and (null l1) (null l2)) nil) ;; l1 not null and l2 null ==> l1 length > l2 length - (l1 (< (version-list-not-zero l1) 0)) + (l1 (minusp (version-list-not-zero l1))) ;; l1 null and l2 not null ==> l2 length > l1 length - (t (< 0 (version-list-not-zero l2))))) + (t (plusp (version-list-not-zero l2))))) (defun version-list-= (l1 l2) diff --git a/lisp/tab-line.el b/lisp/tab-line.el index 5562f5caaf1..552c480725c 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -668,7 +668,7 @@ SELECTED-P nil means TAB is not the selected tab. When TAB is not selected and is even-numbered, make FACE inherit from `tab-line-tab-inactive-alternate'. For use in `tab-line-tab-face-functions'." - (when (and (not selected-p) (cl-evenp (cl-position tab tabs))) + (when (and (not selected-p) (evenp (cl-position tab tabs))) (setf face `(:inherit (tab-line-tab-inactive-alternate ,face)))) face) diff --git a/lisp/term.el b/lisp/term.el index 2258da8fe37..753fffe5ec2 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -3016,7 +3016,7 @@ See `term-prompt-regexp'." (defconst term-control-seq-regexp (concat ;; A control character not matched in a longer sequence below, - "\\(?:[\x00-\x19\x1C-\x1F\r\n\t\b]\\|" + "\\(?:[\x00-\x19\x1C-\x1F]\\|" ;; some Emacs specific control sequences, implemented by ;; `term-command-hook', "\032[^\n]+\n\\|" diff --git a/lisp/term/pgtk-win.el b/lisp/term/pgtk-win.el index fe9807f8c52..1c15234c49c 100644 --- a/lisp/term/pgtk-win.el +++ b/lisp/term/pgtk-win.el @@ -194,6 +194,7 @@ EVENT is a `preedit-text' event." ("etc/images/save" . ("document-save" "gtk-save")) ("etc/images/saveas" . ("document-save-as" "gtk-save-as")) ("etc/images/undo" . ("edit-undo" "gtk-undo")) + ("etc/images/redo" . ("edit-redo" "gtk-redo")) ("etc/images/cut" . ("edit-cut" "gtk-cut")) ("etc/images/copy" . ("edit-copy" "gtk-copy")) ("etc/images/paste" . ("edit-paste" "gtk-paste")) diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index debcb669b76..91b5bd5838a 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -1383,6 +1383,7 @@ This returns an error if any Emacs frames are X frames." ("etc/images/save" . ("document-save" "gtk-save")) ("etc/images/saveas" . ("document-save-as" "gtk-save-as")) ("etc/images/undo" . ("edit-undo" "gtk-undo")) + ("etc/images/redo" . ("edit-redo" "gtk-redo")) ("etc/images/cut" . ("edit-cut" "gtk-cut")) ("etc/images/copy" . ("edit-copy" "gtk-copy")) ("etc/images/paste" . ("edit-paste" "gtk-paste")) diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 53340195386..35c61e4f66d 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -893,13 +893,7 @@ cannot be completed sensibly: `custom-ident', (modify-syntax-entry ?? "." st) st)) -(defvar-keymap css-mode-map - :doc "Keymap used in `css-mode'." - " " #'css-lookup-symbol - ;; `info-complete-symbol' is not used. - " " #'completion-at-point - "C-c C-f" #'css-cycle-color-format - :menu +(defvar css-mode--menu '("CSS" :help "CSS-specific features" ["Reformat block" fill-paragraph @@ -910,7 +904,17 @@ cannot be completed sensibly: `custom-ident', ["Describe symbol" css-lookup-symbol :help "Display documentation for a CSS symbol"] ["Complete symbol" completion-at-point - :help "Complete symbol before point"])) + :help "Complete symbol before point"]) + "Menu bar for `css-mode'") + +(defvar-keymap css-mode-map + :doc "Keymap used in `css-mode'." + " " #'css-lookup-symbol + ;; `info-complete-symbol' is not used. + " " #'completion-at-point + "C-c C-f" #'css-cycle-color-format + :menu + css-mode--menu) (eval-and-compile (defconst css--uri-re @@ -1771,6 +1775,21 @@ rgb()/rgba()." (replace-regexp-in-string "[\n ]+" " " s))) res))))))) +(defvar css--treesit-font-lock-feature-list + '((selector comment query keyword) + (property constant string) + (error variable function operator bracket)) + "Settings for `treesit-font-lock-feature-list'.") + +(defvar css--treesit-simple-imenu-settings + `(( nil ,(rx bos (or "rule_set" "media_statement") eos) + nil nil)) + "Settings for `treesit-simple-imenu'.") + +(defvar css--treesit-defun-type-regexp + "rule_set" + "Settings for `treesit-defun-type-regexp'.") + (define-derived-mode css-base-mode prog-mode "CSS" "Generic mode to edit Cascading Style Sheets (CSS). @@ -1825,16 +1844,12 @@ can also be used to fill comments. ;; Tree-sitter specific setup. (setq treesit-primary-parser (treesit-parser-create 'css)) (setq-local treesit-simple-indent-rules css--treesit-indent-rules) - (setq-local treesit-defun-type-regexp "rule_set") + (setq-local treesit-defun-type-regexp css--treesit-defun-type-regexp) (setq-local treesit-defun-name-function #'css--treesit-defun-name) (setq-local treesit-font-lock-settings css--treesit-settings) - (setq-local treesit-font-lock-feature-list - '((selector comment query keyword) - (property constant string) - (error variable function operator bracket))) - (setq-local treesit-simple-imenu-settings - `(( nil ,(rx bos (or "rule_set" "media_statement") eos) - nil nil))) + (setq-local treesit-font-lock-feature-list css--treesit-font-lock-feature-list) + (setq-local treesit-simple-imenu-settings css--treesit-simple-imenu-settings) + (treesit-major-mode-setup) (add-to-list 'auto-mode-alist '("\\.css\\'" . css-ts-mode)))) diff --git a/lisp/textmodes/dns-mode.el b/lisp/textmodes/dns-mode.el index 074819b3a59..5e0d47120d8 100644 --- a/lisp/textmodes/dns-mode.el +++ b/lisp/textmodes/dns-mode.el @@ -325,7 +325,7 @@ See `dns-mode-ipv6-to-nibbles' for examples." (string-to-number chunk 16))))) (rev-address-nibbles (nreverse (if (and prefix-length - (cl-minusp prefix-length)) + (minusp prefix-length)) (substring expanded-address prefix-length-nibbles) (substring expanded-address 0 prefix-length-nibbles))))) (with-temp-buffer @@ -334,7 +334,7 @@ See `dns-mode-ipv6-to-nibbles' for examples." (insert char) (insert ".")) (if (and prefix-length - (cl-minusp prefix-length)) + (minusp prefix-length)) (delete-char -1) (insert "ip6.arpa.")) (insert " ") diff --git a/lisp/textmodes/html-ts-mode.el b/lisp/textmodes/html-ts-mode.el index 7e6c3e0b7d1..26efe1be726 100644 --- a/lisp/textmodes/html-ts-mode.el +++ b/lisp/textmodes/html-ts-mode.el @@ -41,6 +41,7 @@ (declare-function treesit-parser-create "treesit.c") (declare-function treesit-node-type "treesit.c") +(declare-function treesit-search-subtree "treesit.c") (defcustom html-ts-mode-indent-offset 2 "Number of spaces for each indentation step in `html-ts-mode'." @@ -87,6 +88,35 @@ `((attribute_name) @font-lock-variable-name-face)) "Tree-sitter font-lock settings for `html-ts-mode'.") +(defvar html-ts-mode--treesit-things-settings + `((html + (sexp ,(regexp-opt '("element" + "text" + "attribute" + "value"))) + (list ,(rx (or + ;; Also match script_element and style_element + "element" + ;; HTML comments have the element syntax + "comment"))) + (sentence ,(rx (and bos (or "tag_name" "attribute") eos))) + (text ,(regexp-opt '("comment" "text"))))) + "Settings for `treesit-thing-settings'.") + +(defvar html-ts-mode--treesit-font-lock-feature-list + '((comment keyword definition) + (property string) + () ()) + "Settings for `treesit-font-lock-feature-list'.") + +(defvar html-ts-mode--treesit-simple-imenu-settings + '((nil "element" nil nil)) + "Settings for `treesit-simple-imenu'.") + +(defvar html-ts-mode--treesit-defun-type-regexp + "element" + "Settings for `treesit-defun-type-regexp'.") + (defun html-ts-mode--defun-name (node) "Return the defun name of NODE. Return nil if there is no name or if NODE is not a defun node." @@ -119,33 +149,18 @@ Return nil if there is no name or if NODE is not a defun node." (setq-local treesit-simple-indent-rules html-ts-mode--indent-rules) ;; Navigation. - (setq-local treesit-defun-type-regexp "element") + (setq-local treesit-defun-type-regexp html-ts-mode--treesit-defun-type-regexp) + (setq-local treesit-defun-name-function #'html-ts-mode--defun-name) - (setq-local treesit-thing-settings - `((html - (sexp ,(regexp-opt '("element" - "text" - "attribute" - "value"))) - (list ,(rx (or - ;; Also match script_element and style_element - "element" - ;; HTML comments have the element syntax - "comment"))) - (sentence ,(rx (and bos (or "tag_name" "attribute") eos))) - (text ,(regexp-opt '("comment" "text")))))) + (setq-local treesit-thing-settings html-ts-mode--treesit-things-settings) ;; Font-lock. (setq-local treesit-font-lock-settings html-ts-mode--font-lock-settings) - (setq-local treesit-font-lock-feature-list - '((comment keyword definition) - (property string) - () ())) + (setq-local treesit-font-lock-feature-list html-ts-mode--treesit-font-lock-feature-list) ;; Imenu. - (setq-local treesit-simple-imenu-settings - '((nil "element" nil nil))) + (setq-local treesit-simple-imenu-settings html-ts-mode--treesit-simple-imenu-settings) ;; Outline minor mode. (setq-local treesit-outline-predicate #'html-ts-mode--outline-predicate) diff --git a/lisp/textmodes/mhtml-ts-mode.el b/lisp/textmodes/mhtml-ts-mode.el new file mode 100644 index 00000000000..83f8879f427 --- /dev/null +++ b/lisp/textmodes/mhtml-ts-mode.el @@ -0,0 +1,601 @@ +;;; mhtml-ts-mode.el --- Major mode for HTML using tree-sitter -*- lexical-binding: t; -*- + +;; Copyright (C) 2024-2025 Free Software Foundation, Inc. + +;; Author: Vincenzo Pupillo +;; Maintainer: Vincenzo Pupillo +;; Created: Nov 2024 +;; Keywords: HTML languages hypermedia tree-sitter + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: +;; +;; This package provides `mhtml-ts-mode' which is a major mode +;; for editing HTML files with embedded JavaScript and CSS. +;; Tree Sitter is used to parse each of these languages. +;; +;; Please note that this package requires `html-ts-mode', which +;; registers itself as the major mode for editing HTML. +;; +;; This package is compatible and has been tested with the following +;; tree-sitter grammars: +;; * https://github.com/tree-sitter/tree-sitter-html +;; * https://github.com/tree-sitter/tree-sitter-javascript +;; * https://github.com/tree-sitter/tree-sitter-jsdoc +;; * https://github.com/tree-sitter/tree-sitter-css +;; +;; Features +;; +;; * Indent +;; * Flymake +;; * IMenu +;; * Navigation +;; * Which-function +;; * Tree-sitter parser installation helper + +;;; Code: + +(require 'treesit) +(require 'html-ts-mode) +(require 'css-mode) ;; for embed css into html +(require 'js) ;; for embed javascript into html + +(eval-when-compile + (require 'rx)) + +;; This tells the byte-compiler where the functions are defined. +;; Is only needed when a file needs to be able to byte-compile +;; in a Emacs not built with tree-sitter library. +(treesit-declare-unavailable-functions) + +;; In a multi-language major mode can be useful to have an "installer" to +;; simplify the installation of the grammars supported by the major-mode. +(defvar mhtml-ts-mode--language-source-alist + '((html . ("https://github.com/tree-sitter/tree-sitter-html" "v0.23.2")) + (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript" "v0.23.1")) + (jsdoc . ("https://github.com/tree-sitter/tree-sitter-jsdoc" "v0.23.2")) + (css . ("https://github.com/tree-sitter/tree-sitter-css" "v0.23.1"))) + "Treesitter language parsers required by `mhtml-ts-mode'. +You can customize this variable if you want to stick to a specific +commit and/or use different parsers.") + +(defun mhtml-ts-mode-install-parsers () + "Install all the required treesitter parsers. +`mhtml-ts-mode--language-source-alist' defines which parsers to install." + (interactive) + (let ((treesit-language-source-alist mhtml-ts-mode--language-source-alist)) + (dolist (item mhtml-ts-mode--language-source-alist) + (treesit-install-language-grammar (car item))))) + +;;; Custom variables + +(defgroup mhtml-ts-mode nil + "Major mode for editing HTML files, based on `html-ts-mode'. +Works with JS and CSS and for that use `js-ts-mode' and `css-ts-mode'." + :prefix "mhtml-ts-mode-" + ;; :group 'languages + :group 'html) + +(defcustom mhtml-ts-mode-js-css-indent-offset 2 + "JavaScript and CSS indent spaces related to the + +When nil, indentation of the tag body starts just below the +tag, like: + + + +When `ignore', the tag body starts in the first column, like: + + " + :type '(choice (const nil) (const t) (const ignore)) + :safe 'symbolp + :set #'mhtml-ts-mode--tag-relative-indent-offset + :version "31.1") + +(defcustom mhtml-ts-mode-css-fontify-colors t + "Whether CSS colors should be fontified using the color as the background. +If non-nil, text representing a CSS color will be fontified +such that its background is the color itself. +Works like `css--fontify-region'." + :tag "HTML colors the CSS properties values." + :version "31.1" + :type 'boolean + :safe 'booleanp) + +(defvar mhtml-ts-mode-saved-pretty-print-command nil + "The command last used to pretty print in this buffer.") + +(defun mhtml-ts-mode-pretty-print (command) + "Prettify the current buffer. +Argument COMMAND The command to use." + (interactive + (list (read-string + "Prettify command: " + (or mhtml-ts-mode-saved-pretty-print-command + (concat mhtml-ts-mode-pretty-print-command " "))))) + (setq mhtml-ts-mode-saved-pretty-print-command command) + (save-excursion + (shell-command-on-region + (point-min) (point-max) + command (buffer-name) t + "*mhtml-ts-mode-pretty-pretty-print-errors*" t))) + +(defun mhtml-ts-mode--switch-fill-defun (&rest arguments) + "Switch between `fill-paragraph' and `prog-fill-reindent-defun'. +In an HTML region it calls `fill-paragraph' as does `html-ts-mode', +otherwise it calls `prog-fill-reindent-defun'. +Optional ARGUMENTS to to be passed to it." + (interactive) + (if (eq (treesit-language-at (point)) 'html) + (funcall-interactively #'fill-paragraph arguments) + (funcall-interactively #'prog-fill-reindent-defun arguments))) + +(defvar-keymap mhtml-ts-mode-map + :doc "Keymap for `mhtml-ts-mode' buffers." + :parent html-mode-map + ;; `mhtml-ts-mode' derive from `html-ts-mode' so the keymap is the + ;; same, we need to add some mapping from others languages. + "C-c C-f" #'css-cycle-color-format + "M-q" #'mhtml-ts-mode--switch-fill-defun) + +;; Place the CSS menu in the menu bar as well. +(easy-menu-define mhtml-ts-mode-menu mhtml-ts-mode-map + "Menu bar for `mhtml-ts-mode'." + css-mode--menu) + +;; To enable some basic treesiter functionality, you should define +;; a function that recognizes which grammar is used at-point. +;; This function should be assigned to `treesit-language-at-point-function' +(defun mhtml-ts-mode--language-at-point (point) + "Return the language at POINT assuming the point is within a HTML buffer." + (let* ((node (treesit-node-at point 'html)) + (parent (treesit-node-parent node)) + (node-query (format "(%s (%s))" + (treesit-node-type parent) + (treesit-node-type node)))) + (cond + ((equal "(script_element (raw_text))" node-query) (js--treesit-language-at-point point)) + ((equal "(style_element (raw_text))" node-query) 'css) + (t 'html)))) + +;; Custom font-lock function that's used to apply color to css color +;; The signature of the function should be conforming to signature +;; QUERY-SPEC required by `treesit-font-lock-rules'. +(defun mhtml-ts-mode--colorize-css-value (node override start end &rest _) + "Colorize CSS property value like `css--fontify-region'. +For NODE, OVERRIDE, START, and END, see `treesit-font-lock-rules'." + (if (and mhtml-ts-mode-css-fontify-colors + (string-equal "plain_value" (treesit-node-type node))) + (let ((color (css--compute-color start (treesit-node-text node t)))) + (when color + (with-silent-modifications + (add-text-properties + (treesit-node-start node) (treesit-node-end node) + (list 'face (list :background color + :foreground (readable-foreground-color + color) + :box '(:line-width -1))))))) + (treesit-fontify-with-override + (treesit-node-start node) (treesit-node-end node) + 'font-lock-variable-name-face + override start end))) + +;; Embedded languages should be indented according to the language +;; that embeds them. +;; This function signature complies with `treesit-simple-indent-rules' +;; ANCHOR. +(defun mhtml-ts-mode--js-css-tag-bol (_node _parent &rest _) + "Find the first non-space characters of html tags