summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2022-10-16 17:24:26 -0700
committerSean Whitton <spwhitton@spwhitton.name>2022-10-16 17:24:26 -0700
commitbc1a4071bb67879f0c1a18db93d8b09c1e050885 (patch)
tree3da0e75df8d14e3d4297f82bf990d2f96b47d794
parenta4e186248608afb4618a27275113bb70966a4f52 (diff)
parent0ff389c0c17b0b2938e79640e86b594344f20e55 (diff)
downloademacs-bc1a4071bb67879f0c1a18db93d8b09c1e050885.tar.gz
Merge remote-tracking branch 'origin/master' into athena/unstable
-rw-r--r--.dir-locals.el2
-rw-r--r--.gitignore1
-rw-r--r--.mailmap197
-rw-r--r--ChangeLog.12
-rw-r--r--ChangeLog.36
-rw-r--r--GNUmakefile2
-rw-r--r--INSTALL2
-rw-r--r--Makefile.in113
-rw-r--r--admin/admin.el198
-rwxr-xr-xadmin/automerge2
-rw-r--r--admin/charsets/mapfiles/stdenc.txt2
-rw-r--r--admin/charsets/mapfiles/symbol.txt2
-rwxr-xr-xadmin/emake46
-rw-r--r--admin/gitmerge.el31
-rw-r--r--admin/grammars/Makefile.in2
-rwxr-xr-xadmin/make-manuals2
-rw-r--r--admin/make-tarball.txt30
-rwxr-xr-xadmin/merge-gnulib4
-rw-r--r--admin/notes/repo11
-rw-r--r--admin/notes/unicode4
-rw-r--r--admin/notes/www4
-rw-r--r--admin/unidata/BidiBrackets.txt6
-rw-r--r--admin/unidata/BidiMirroring.txt8
-rw-r--r--admin/unidata/Blocks.txt21
-rw-r--r--admin/unidata/IVD_Sequences.txt6
-rw-r--r--admin/unidata/IdnaMappingTable.txt169
-rw-r--r--admin/unidata/Makefile.in3
-rw-r--r--admin/unidata/NormalizationTest.txt92
-rw-r--r--admin/unidata/PropertyValueAliases.txt24
-rw-r--r--admin/unidata/README14
-rw-r--r--admin/unidata/ScriptExtensions.txt10
-rw-r--r--admin/unidata/Scripts.txt106
-rw-r--r--admin/unidata/SpecialCasing.txt10
-rw-r--r--admin/unidata/UnicodeData.txt300
-rwxr-xr-xadmin/unidata/blocks.awk2
-rw-r--r--admin/unidata/confusables.txt22
-rw-r--r--admin/unidata/copyright.html24
-rw-r--r--admin/unidata/emoji-data.txt73
-rw-r--r--admin/unidata/emoji-sequences.txt343
-rw-r--r--admin/unidata/emoji-test.txt125
-rw-r--r--admin/unidata/emoji-zwj-sequences.txt13
-rw-r--r--admin/unidata/unidata-gen.el10
-rwxr-xr-xadmin/update-copyright2
-rwxr-xr-xadmin/update_autogen4
-rwxr-xr-xadmin/upload-manuals1
-rwxr-xr-xbuild-aux/config.guess4
-rwxr-xr-xbuild-aux/config.sub4
-rw-r--r--config.bat1
-rw-r--r--configure.ac24
-rw-r--r--doc/emacs/ack.texi8
-rw-r--r--doc/emacs/buffers.texi12
-rw-r--r--doc/emacs/custom.texi10
-rw-r--r--doc/emacs/dired.texi29
-rw-r--r--doc/emacs/emacs.texi1
-rw-r--r--doc/emacs/files.texi13
-rw-r--r--doc/emacs/frames.texi11
-rw-r--r--doc/emacs/help.texi9
-rw-r--r--doc/emacs/maintaining.texi37
-rw-r--r--doc/emacs/misc.texi18
-rw-r--r--doc/emacs/modes.texi7
-rw-r--r--doc/emacs/mule.texi40
-rw-r--r--doc/emacs/package.texi14
-rw-r--r--doc/emacs/programs.texi21
-rw-r--r--doc/emacs/regs.texi3
-rw-r--r--doc/emacs/text.texi17
-rw-r--r--doc/emacs/vc1-xtra.texi51
-rw-r--r--doc/lispintro/emacs-lisp-intro.texi5
-rw-r--r--doc/lispref/buffers.texi10
-rw-r--r--doc/lispref/compile.texi18
-rw-r--r--doc/lispref/control.texi47
-rw-r--r--doc/lispref/customize.texi24
-rw-r--r--doc/lispref/display.texi34
-rw-r--r--doc/lispref/edebug.texi5
-rw-r--r--doc/lispref/eval.texi7
-rw-r--r--doc/lispref/files.texi36
-rw-r--r--doc/lispref/frames.texi32
-rw-r--r--doc/lispref/functions.texi11
-rw-r--r--doc/lispref/help.texi2
-rw-r--r--doc/lispref/internals.texi4
-rw-r--r--doc/lispref/loading.texi2
-rw-r--r--doc/lispref/nonascii.texi2
-rw-r--r--doc/lispref/os.texi3
-rw-r--r--doc/lispref/sequences.texi13
-rw-r--r--doc/lispref/strings.texi24
-rw-r--r--doc/lispref/symbols.texi5
-rw-r--r--doc/lispref/text.texi9
-rw-r--r--doc/lispref/variables.texi47
-rw-r--r--doc/lispref/windows.texi20
-rw-r--r--doc/misc/calc.texi4
-rw-r--r--doc/misc/cc-mode.texi8
-rw-r--r--doc/misc/ede.texi5
-rw-r--r--doc/misc/efaq-w32.texi8
-rw-r--r--doc/misc/efaq.texi9
-rw-r--r--doc/misc/eieio.texi12
-rw-r--r--doc/misc/eshell.texi2
-rw-r--r--doc/misc/gnus-coding.texi227
-rw-r--r--doc/misc/gnus-faq.texi302
-rw-r--r--doc/misc/gnus.texi8
-rw-r--r--doc/misc/mh-e.texi14
-rw-r--r--doc/misc/modus-themes.org109
-rw-r--r--doc/misc/org.org32
-rw-r--r--doc/misc/rcirc.texi71
-rw-r--r--doc/misc/remember.texi7
-rw-r--r--doc/misc/semantic.texi2
-rw-r--r--doc/misc/sieve.texi2
-rw-r--r--doc/misc/texinfo.tex113
-rw-r--r--doc/misc/tramp.texi51
-rw-r--r--doc/misc/vhdl-mode.texi2
-rw-r--r--etc/DEBUG2
-rw-r--r--etc/ERC-NEWS20
-rw-r--r--etc/HELLO8
-rw-r--r--etc/HISTORY2
-rw-r--r--etc/NEWS651
-rw-r--r--etc/NEWS.212
-rw-r--r--etc/NEWS.225
-rw-r--r--etc/NEWS.232
-rw-r--r--etc/NEWS.252
-rw-r--r--etc/NEWS.262
-rw-r--r--etc/NEWS.2869
-rw-r--r--etc/TODO47
-rw-r--r--etc/images/checked.xpm19
-rw-r--r--etc/images/gnus/gnus-pointer.xpm6
-rw-r--r--etc/images/gnus/gnus.xpm4
-rw-r--r--etc/images/gud/README4
-rw-r--r--etc/images/mh-logo.xpm28
-rw-r--r--etc/images/outline-close.pbmbin0 -> 39 bytes
-rw-r--r--etc/images/outline-close.svg6
-rw-r--r--etc/images/outline-open.pbmbin0 -> 39 bytes
-rw-r--r--etc/images/outline-open.svg4
-rw-r--r--etc/images/unchecked.xpm19
-rw-r--r--etc/publicsuffix.txt55
-rw-r--r--etc/srecode/ede-autoconf.srt2
-rw-r--r--etc/srecode/ede-make.srt4
-rw-r--r--etc/themes/adwaita-theme.el5
-rw-r--r--etc/themes/deeper-blue-theme.el5
-rw-r--r--etc/themes/dichromacy-theme.el5
-rw-r--r--etc/themes/leuven-dark-theme.el8
-rw-r--r--etc/themes/leuven-theme.el8
-rw-r--r--etc/themes/light-blue-theme.el5
-rw-r--r--etc/themes/manoj-dark-theme.el5
-rw-r--r--etc/themes/misterioso-theme.el5
-rw-r--r--etc/themes/modus-operandi-theme.el4
-rw-r--r--etc/themes/modus-themes.el50
-rw-r--r--etc/themes/modus-vivendi-theme.el4
-rw-r--r--etc/themes/tango-dark-theme.el7
-rw-r--r--etc/themes/tango-theme.el6
-rw-r--r--etc/themes/tsdh-dark-theme.el6
-rw-r--r--etc/themes/tsdh-light-theme.el6
-rw-r--r--etc/themes/wheatgrass-theme.el5
-rw-r--r--etc/themes/whiteboard-theme.el5
-rw-r--r--etc/themes/wombat-theme.el5
-rw-r--r--etc/tutorials/TUTORIAL.translators4
-rw-r--r--etc/tutorials/TUTORIAL.uk1150
-rw-r--r--leim/Makefile.in2
-rw-r--r--lib-src/Makefile.in8
-rw-r--r--lib-src/seccomp-filter.c43
-rw-r--r--lib/acl-internal.h1
-rw-r--r--lib/acl.h1
-rw-r--r--lib/assert.in.h27
-rw-r--r--lib/c-ctype.h2
-rw-r--r--lib/canonicalize-lgpl.c1
-rw-r--r--lib/cloexec.h2
-rw-r--r--lib/close-stream.c1
-rw-r--r--lib/count-leading-zeros.h20
-rw-r--r--lib/count-trailing-zeros.h16
-rw-r--r--lib/diffseq.h1
-rw-r--r--lib/filevercmp.c4
-rw-r--r--lib/fsusage.h1
-rw-r--r--lib/getloadavg.c1
-rw-r--r--lib/getrandom.c1
-rw-r--r--lib/gnulib.mk.in39
-rw-r--r--lib/malloc/dynarray.h1
-rw-r--r--lib/md5.c1
-rw-r--r--lib/mini-gmp.c5
-rw-r--r--lib/nanosleep.c4
-rw-r--r--lib/nstrftime.c1
-rw-r--r--lib/openat.h1
-rw-r--r--lib/pipe2.c3
-rw-r--r--lib/rawmemchr.c4
-rw-r--r--lib/regex_internal.h1
-rw-r--r--lib/sha1.c1
-rw-r--r--lib/sha256.c1
-rw-r--r--lib/sha512.c1
-rw-r--r--lib/signal.in.h14
-rw-r--r--lib/stdalign.in.h24
-rw-r--r--lib/stdckdint.in.h2
-rw-r--r--lib/stdlib.in.h6
-rw-r--r--lib/string.in.h2
-rw-r--r--lib/strtoimax.c6
-rw-r--r--lib/sys_random.in.h2
-rw-r--r--lib/sys_select.in.h9
-rw-r--r--lib/sys_stat.in.h76
-rw-r--r--lib/tempname.c1
-rw-r--r--lib/time.in.h4
-rw-r--r--lib/time_rz.c1
-rw-r--r--lib/unistd.in.h4
-rw-r--r--lib/utimens.c1
-rw-r--r--lib/verify.h39
-rw-r--r--lisp/ChangeLog.102
-rw-r--r--lisp/ChangeLog.144
-rw-r--r--lisp/ChangeLog.152
-rw-r--r--lisp/ChangeLog.172
-rw-r--r--lisp/Makefile.in36
-rw-r--r--lisp/abbrev.el20
-rw-r--r--lisp/allout-widgets.el4
-rw-r--r--lisp/ansi-osc.el203
-rw-r--r--lisp/auth-source-pass.el10
-rw-r--r--lisp/auth-source.el15
-rw-r--r--lisp/autoinsert.el43
-rw-r--r--lisp/autorevert.el2
-rw-r--r--lisp/battery.el16
-rw-r--r--lisp/bookmark.el21
-rw-r--r--lisp/calc/calc-embed.el5
-rw-r--r--lisp/calc/calc-stuff.el8
-rw-r--r--lisp/calc/calc-yank.el12
-rw-r--r--lisp/calc/calc.el11
-rw-r--r--lisp/calendar/cal-move.el5
-rw-r--r--lisp/cedet/ede/autoconf-edit.el3
-rw-r--r--lisp/cedet/pulse.el10
-rw-r--r--lisp/cedet/semantic/ede-grammar.el7
-rw-r--r--lisp/cedet/semantic/edit.el8
-rw-r--r--lisp/cedet/semantic/grammar.el8
-rw-r--r--lisp/cedet/semantic/mru-bookmark.el8
-rw-r--r--lisp/cedet/semantic/util-modes.el36
-rw-r--r--lisp/cedet/srecode/fields.el4
-rw-r--r--lisp/cedet/srecode/insert.el4
-rw-r--r--lisp/cedet/srecode/srt-mode.el12
-rw-r--r--lisp/comint.el146
-rw-r--r--lisp/cus-dep.el2
-rw-r--r--lisp/cus-start.el1
-rw-r--r--lisp/custom.el80
-rw-r--r--lisp/dabbrev.el3
-rw-r--r--lisp/dired-aux.el4
-rw-r--r--lisp/dired.el22
-rw-r--r--lisp/dnd.el16
-rw-r--r--lisp/doc-view.el126
-rw-r--r--lisp/ecomplete.el103
-rw-r--r--lisp/emacs-lisp/benchmark.el3
-rw-r--r--lisp/emacs-lisp/byte-opt.el34
-rw-r--r--lisp/emacs-lisp/bytecomp.el8
-rw-r--r--lisp/emacs-lisp/cconv.el51
-rw-r--r--lisp/emacs-lisp/checkdoc.el6
-rw-r--r--lisp/emacs-lisp/cl-generic.el32
-rw-r--r--lisp/emacs-lisp/cl-macs.el24
-rw-r--r--lisp/emacs-lisp/comp.el53
-rw-r--r--lisp/emacs-lisp/debug.el8
-rw-r--r--lisp/emacs-lisp/edebug.el6
-rw-r--r--lisp/emacs-lisp/eieio-core.el18
-rw-r--r--lisp/emacs-lisp/eieio.el20
-rw-r--r--lisp/emacs-lisp/ert-x.el30
-rw-r--r--lisp/emacs-lisp/gv.el13
-rw-r--r--lisp/emacs-lisp/icons.el6
-rw-r--r--lisp/emacs-lisp/lisp-mode.el27
-rw-r--r--lisp/emacs-lisp/loaddefs-gen.el29
-rw-r--r--lisp/emacs-lisp/memory-report.el7
-rw-r--r--lisp/emacs-lisp/nadvice.el47
-rw-r--r--lisp/emacs-lisp/oclosure.el15
-rw-r--r--lisp/emacs-lisp/package.el53
-rw-r--r--lisp/emacs-lisp/regexp-opt.el1
-rw-r--r--lisp/emacs-lisp/seq.el4
-rw-r--r--lisp/emacs-lisp/shortdoc.el60
-rw-r--r--lisp/emacs-lisp/subr-x.el1
-rw-r--r--lisp/emacs-lisp/testcover.el3
-rw-r--r--lisp/emacs-lisp/vtable.el17
-rw-r--r--lisp/epa-hook.el8
-rw-r--r--lisp/epa-ks.el18
-rw-r--r--lisp/epa.el48
-rw-r--r--lisp/epg.el8
-rw-r--r--lisp/erc/ChangeLog.14
-rw-r--r--lisp/erc/erc-button.el1
-rw-r--r--lisp/erc/erc-match.el55
-rw-r--r--lisp/erc/erc-networks.el4
-rw-r--r--lisp/erc/erc.el19
-rw-r--r--lisp/eshell/em-cmpl.el29
-rw-r--r--lisp/eshell/em-glob.el2
-rw-r--r--lisp/eshell/em-script.el3
-rw-r--r--lisp/eshell/em-smart.el3
-rw-r--r--lisp/eshell/em-unix.el6
-rw-r--r--lisp/eshell/esh-arg.el3
-rw-r--r--lisp/eshell/esh-cmd.el3
-rw-r--r--lisp/eshell/esh-mode.el3
-rw-r--r--lisp/eshell/esh-proc.el18
-rw-r--r--lisp/eshell/esh-var.el35
-rw-r--r--lisp/faces.el3
-rw-r--r--lisp/ffap.el6
-rw-r--r--lisp/filenotify.el1
-rw-r--r--lisp/files-x.el4
-rw-r--r--lisp/files.el155
-rw-r--r--lisp/font-lock.el20
-rw-r--r--lisp/format-spec.el17
-rw-r--r--lisp/format.el7
-rw-r--r--lisp/forms.el6
-rw-r--r--lisp/frame.el30
-rw-r--r--lisp/gnus/gnus-art.el222
-rw-r--r--lisp/gnus/gnus-cite.el22
-rw-r--r--lisp/gnus/gnus-cus.el4
-rw-r--r--lisp/gnus/gnus-gravatar.el1
-rw-r--r--lisp/gnus/gnus-group.el74
-rw-r--r--lisp/gnus/gnus-rfc1843.el3
-rw-r--r--lisp/gnus/gnus-search.el8
-rw-r--r--lisp/gnus/gnus-srvr.el7
-rw-r--r--lisp/gnus/gnus-sum.el4
-rw-r--r--lisp/gnus/gnus-util.el5
-rw-r--r--lisp/gnus/gnus.el30
-rw-r--r--lisp/gnus/message.el70
-rw-r--r--lisp/gnus/mm-uu.el2
-rw-r--r--lisp/gnus/nndoc.el2
-rw-r--r--lisp/gnus/score-mode.el12
-rw-r--r--lisp/gnus/smime.el10
-rw-r--r--lisp/help-fns.el74
-rw-r--r--lisp/help.el146
-rw-r--r--lisp/hexl.el2
-rw-r--r--lisp/hilit-chg.el1
-rw-r--r--lisp/hl-line.el7
-rw-r--r--lisp/htmlfontify.el24
-rw-r--r--lisp/ielm.el12
-rw-r--r--lisp/image-file.el7
-rw-r--r--lisp/image-mode.el67
-rw-r--r--lisp/image.el68
-rw-r--r--lisp/image/exif.el14
-rw-r--r--lisp/image/image-crop.el452
-rw-r--r--lisp/image/image-dired-dired.el84
-rw-r--r--lisp/image/image-dired-external.el108
-rw-r--r--lisp/image/image-dired-tags.el48
-rw-r--r--lisp/image/image-dired-util.el82
-rw-r--r--lisp/image/image-dired.el979
-rw-r--r--lisp/image/wallpaper.el586
-rw-r--r--lisp/imenu.el18
-rw-r--r--lisp/indent.el10
-rw-r--r--lisp/info.el5
-rw-r--r--lisp/international/characters.el62
-rw-r--r--lisp/international/fontset.el41
-rw-r--r--lisp/international/mule-cmds.el33
-rw-r--r--lisp/international/mule.el17
-rw-r--r--lisp/international/rfc1843.el5
-rw-r--r--lisp/international/textsec-check.el2
-rw-r--r--lisp/international/titdic-cnv.el10
-rw-r--r--lisp/isearch.el23
-rw-r--r--lisp/jit-lock.el26
-rw-r--r--lisp/language/cyrillic.el14
-rw-r--r--lisp/language/ethio-util.el43
-rw-r--r--lisp/language/indian.el30
-rw-r--r--lisp/language/indonesian.el21
-rw-r--r--lisp/language/lao.el6
-rw-r--r--lisp/language/misc-lang.el74
-rw-r--r--lisp/language/philippine.el12
-rw-r--r--lisp/ldefs-boot.el782
-rw-r--r--lisp/leim/quail/indian.el114
-rw-r--r--lisp/leim/quail/misc-lang.el495
-rw-r--r--lisp/loadup.el4
-rw-r--r--lisp/mail/emacsbug.el9
-rw-r--r--lisp/mail/feedmail.el25
-rw-r--r--lisp/mail/hashcash.el25
-rw-r--r--lisp/mail/rmail.el22
-rw-r--r--lisp/mh-e/mh-e.el4
-rw-r--r--lisp/mh-e/mh-junk.el4
-rw-r--r--lisp/minibuf-eldef.el3
-rw-r--r--lisp/net/browse-url.el5
-rw-r--r--lisp/net/dictionary.el2
-rw-r--r--lisp/net/eww.el55
-rw-r--r--lisp/net/goto-addr.el89
-rw-r--r--lisp/net/mailcap.el15
-rw-r--r--lisp/net/pop3.el2
-rw-r--r--lisp/net/rcirc.el203
-rw-r--r--lisp/net/shr.el78
-rw-r--r--lisp/net/sieve-mode.el8
-rw-r--r--lisp/net/tramp-archive.el13
-rw-r--r--lisp/net/tramp-cache.el25
-rw-r--r--lisp/net/tramp-cmds.el4
-rw-r--r--lisp/net/tramp-compat.el8
-rw-r--r--lisp/net/tramp-container.el190
-rw-r--r--lisp/net/tramp-crypt.el8
-rw-r--r--lisp/net/tramp-gvfs.el3
-rw-r--r--lisp/net/tramp-integration.el16
-rw-r--r--lisp/net/tramp-sh.el20
-rw-r--r--lisp/net/tramp-smb.el2
-rw-r--r--lisp/net/tramp-sshfs.el3
-rw-r--r--lisp/net/tramp-sudoedit.el59
-rw-r--r--lisp/net/tramp-uu.el2
-rw-r--r--lisp/net/tramp.el30
-rw-r--r--lisp/nxml/nxml-mode.el6
-rw-r--r--lisp/nxml/nxml-util.el6
-rw-r--r--lisp/nxml/rng-nxml.el77
-rw-r--r--lisp/nxml/rng-valid.el37
-rw-r--r--lisp/obsolete/linum.el (renamed from lisp/linum.el)16
-rw-r--r--lisp/obsolete/thumbs.el (renamed from lisp/thumbs.el)23
-rw-r--r--lisp/obsolete/vc-arch.el2
-rw-r--r--lisp/obsolete/vc-mtn.el2
-rw-r--r--lisp/org/ob-matlab.el2
-rw-r--r--lisp/org/ob-plantuml.el2
-rw-r--r--lisp/org/org-ctags.el2
-rw-r--r--lisp/org/org-macro.el2
-rw-r--r--lisp/org/org-protocol.el2
-rw-r--r--lisp/org/org.el12
-rw-r--r--lisp/org/ox.el2
-rw-r--r--lisp/outline.el422
-rw-r--r--lisp/pcmpl-git.el110
-rw-r--r--lisp/pcmpl-gnu.el36
-rw-r--r--lisp/pcmpl-linux.el68
-rw-r--r--lisp/pcmpl-rpm.el43
-rw-r--r--lisp/pcmpl-unix.el490
-rw-r--r--lisp/pcmpl-x.el43
-rw-r--r--lisp/pcomplete.el153
-rw-r--r--lisp/pixel-scroll.el117
-rw-r--r--lisp/play/hanoi.el5
-rw-r--r--lisp/play/zone.el36
-rw-r--r--lisp/printing.el18
-rw-r--r--lisp/proced.el50
-rw-r--r--lisp/progmodes/antlr-mode.el18
-rw-r--r--lisp/progmodes/cc-align.el13
-rw-r--r--lisp/progmodes/cc-awk.el25
-rw-r--r--lisp/progmodes/cc-defs.el47
-rw-r--r--lisp/progmodes/cc-engine.el560
-rw-r--r--lisp/progmodes/cc-fonts.el300
-rw-r--r--lisp/progmodes/cc-langs.el121
-rw-r--r--lisp/progmodes/cc-mode.el112
-rw-r--r--lisp/progmodes/compile.el13
-rw-r--r--lisp/progmodes/cperl-mode.el55
-rw-r--r--lisp/progmodes/elisp-mode.el4
-rw-r--r--lisp/progmodes/etags.el4
-rw-r--r--lisp/progmodes/flymake.el2
-rw-r--r--lisp/progmodes/gdb-mi.el2
-rw-r--r--lisp/progmodes/glasses.el16
-rw-r--r--lisp/progmodes/hideif.el4
-rw-r--r--lisp/progmodes/hideshow.el57
-rw-r--r--lisp/progmodes/make-mode.el21
-rw-r--r--lisp/progmodes/opascal.el3
-rw-r--r--lisp/progmodes/perl-mode.el7
-rw-r--r--lisp/progmodes/prog-mode.el8
-rw-r--r--lisp/progmodes/project.el2
-rw-r--r--lisp/progmodes/python.el67
-rw-r--r--lisp/progmodes/sh-script.el90
-rw-r--r--lisp/progmodes/subword.el5
-rw-r--r--lisp/progmodes/verilog-mode.el13
-rw-r--r--lisp/progmodes/vhdl-mode.el7
-rw-r--r--lisp/progmodes/xref.el19
-rw-r--r--lisp/repeat.el72
-rw-r--r--lisp/replace.el4
-rw-r--r--lisp/reveal.el12
-rw-r--r--lisp/server.el19
-rw-r--r--lisp/shell.el35
-rw-r--r--lisp/simple.el261
-rw-r--r--lisp/startup.el11
-rw-r--r--lisp/strokes.el8
-rw-r--r--lisp/subr.el104
-rw-r--r--lisp/tab-bar.el1
-rw-r--r--lisp/tab-line.el68
-rw-r--r--lisp/tar-mode.el2
-rw-r--r--lisp/term/haiku-win.el39
-rw-r--r--lisp/term/pgtk-win.el1
-rw-r--r--lisp/term/x-win.el93
-rw-r--r--lisp/textmodes/bibtex.el132
-rw-r--r--lisp/textmodes/emacs-news-mode.el12
-rw-r--r--lisp/textmodes/enriched.el3
-rw-r--r--lisp/textmodes/flyspell.el10
-rw-r--r--lisp/textmodes/ispell.el3
-rw-r--r--lisp/textmodes/less-css-mode.el8
-rw-r--r--lisp/textmodes/page-ext.el54
-rw-r--r--lisp/textmodes/picture.el174
-rw-r--r--lisp/textmodes/remember.el20
-rw-r--r--lisp/textmodes/sgml-mode.el4
-rw-r--r--lisp/textmodes/string-edit.el12
-rw-r--r--lisp/textmodes/table.el19
-rw-r--r--lisp/textmodes/tex-mode.el73
-rw-r--r--lisp/time.el10
-rw-r--r--lisp/url/url-file.el1
-rw-r--r--lisp/url/url-handlers.el19
-rw-r--r--lisp/url/url.el4
-rw-r--r--lisp/vc/add-log.el2
-rw-r--r--lisp/vc/log-edit.el7
-rw-r--r--lisp/vc/log-view.el1
-rw-r--r--lisp/vc/vc-bzr.el16
-rw-r--r--lisp/vc/vc-cvs.el2
-rw-r--r--lisp/vc/vc-dir.el6
-rw-r--r--lisp/vc/vc-dispatcher.el258
-rw-r--r--lisp/vc/vc-git.el183
-rw-r--r--lisp/vc/vc-hg.el14
-rw-r--r--lisp/vc/vc-hooks.el3
-rw-r--r--lisp/vc/vc-svn.el2
-rw-r--r--lisp/vc/vc.el230
-rw-r--r--lisp/view.el7
-rw-r--r--lisp/whitespace.el65
-rw-r--r--lisp/wid-browse.el18
-rw-r--r--lisp/wid-edit.el8
-rw-r--r--lisp/window.el3
-rw-r--r--lisp/winner.el6
-rw-r--r--lisp/x-dnd.el5
-rw-r--r--lisp/xdg.el25
-rw-r--r--m4/assert_h.m461
-rw-r--r--m4/c-bool.m451
-rw-r--r--m4/gettime.m431
-rw-r--r--m4/gnulib-common.m44
-rw-r--r--m4/gnulib-comp.m411
-rw-r--r--m4/nanosleep.m417
-rw-r--r--m4/stdalign.m4104
-rw-r--r--m4/time_h.m48
-rw-r--r--msdos/sed2v2.inp1
-rw-r--r--msdos/sedlibmk.inp19
-rw-r--r--nextstep/Makefile.in2
-rw-r--r--nt/INSTALL24
-rw-r--r--nt/INSTALL.W642
-rw-r--r--nt/Makefile.in4
-rw-r--r--src/ChangeLog.134
-rw-r--r--src/bytecode.c4
-rw-r--r--src/coding.c6
-rw-r--r--src/comp.c88
-rw-r--r--src/composite.c50
-rw-r--r--src/composite.h1
-rw-r--r--src/conf_post.h6
-rw-r--r--src/data.c1
-rw-r--r--src/dbusbind.c4
-rw-r--r--src/dired.c5
-rw-r--r--src/dispnew.c9
-rw-r--r--src/doc.c2
-rw-r--r--src/dynlib.h1
-rw-r--r--src/editfns.c11
-rw-r--r--src/emacs-module.c1
-rw-r--r--src/emacs-module.h.in3
-rw-r--r--src/emacs.c22
-rw-r--r--src/eval.c67
-rw-r--r--src/fileio.c24
-rw-r--r--src/fns.c136
-rw-r--r--src/font.c594
-rw-r--r--src/font.h2
-rw-r--r--src/fontset.c3
-rw-r--r--src/frame.c30
-rw-r--r--src/ftcrfont.c32
-rw-r--r--src/haiku_font_support.cc282
-rw-r--r--src/haiku_io.c2
-rw-r--r--src/haiku_support.cc53
-rw-r--r--src/haiku_support.h34
-rw-r--r--src/haikufns.c6
-rw-r--r--src/haikufont.c109
-rw-r--r--src/haikuselect.c129
-rw-r--r--src/haikuterm.c29
-rw-r--r--src/haikuterm.h6
-rw-r--r--src/hbfont.c2
-rw-r--r--src/image.c46
-rw-r--r--src/intervals.c4
-rw-r--r--src/keyboard.c28
-rw-r--r--src/lisp.h18
-rw-r--r--src/lread.c46
-rw-r--r--src/macuvs.h1762
-rw-r--r--src/menu.c4
-rw-r--r--src/minibuf.c12
-rw-r--r--src/nsmenu.m5
-rw-r--r--src/nsterm.m45
-rw-r--r--src/pdumper.c2
-rw-r--r--src/sqlite.c173
-rw-r--r--src/sysdep.c7
-rw-r--r--src/systhread.h2
-rw-r--r--src/term.c40
-rw-r--r--src/termchar.h5
-rw-r--r--src/textprop.c10
-rw-r--r--src/w32fns.c65
-rw-r--r--src/widget.c42
-rw-r--r--src/widget.h2
-rw-r--r--src/widgetprv.h3
-rw-r--r--src/window.c99
-rw-r--r--src/xdisp.c54
-rw-r--r--src/xfns.c131
-rw-r--r--src/xfont.c34
-rw-r--r--src/xsettings.c16
-rw-r--r--src/xsmfns.c4
-rw-r--r--src/xterm.c915
-rw-r--r--src/xterm.h18
-rw-r--r--test/lisp/ansi-osc-tests.el57
-rw-r--r--test/lisp/calendar/icalendar-tests.el2
-rw-r--r--test/lisp/cedet/semantic-utest.el1
-rw-r--r--test/lisp/dnd-tests.el12
-rw-r--r--test/lisp/electric-tests.el2
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/warn-variable-set-nonvariable.el3
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-function-signature.el4
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el19
-rw-r--r--test/lisp/emacs-lisp/cconv-tests.el10
-rw-r--r--test/lisp/emacs-lisp/cl-macs-tests.el56
-rw-r--r--test/lisp/emacs-lisp/package-resources/key.pub25
-rw-r--r--test/lisp/emacs-lisp/package-resources/key.sec27
-rw-r--r--test/lisp/emacs-lisp/package-resources/signed/archive-contents.sigbin95 -> 119 bytes
-rw-r--r--test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el.sigbin95 -> 119 bytes
-rwxr-xr-xtest/lisp/emacs-lisp/package-resources/signed/update-signatures.sh7
-rw-r--r--test/lisp/emacs-lisp/package-resources/ustar-withsub-0.1.tarbin0 -> 10240 bytes
-rw-r--r--test/lisp/emacs-lisp/package-resources/v7-withsub-0.1.tarbin0 -> 10240 bytes
-rw-r--r--test/lisp/emacs-lisp/package-tests.el24
-rw-r--r--test/lisp/emacs-lisp/seq-tests.el6
-rw-r--r--test/lisp/epg-resources/pubkey.asc28
-rw-r--r--test/lisp/epg-resources/seckey.asc43
-rw-r--r--test/lisp/epg-tests.el19
-rw-r--r--test/lisp/erc/erc-match-tests.el193
-rw-r--r--test/lisp/erc/erc-scenarios-base-reconnect.el45
-rw-r--r--test/lisp/erc/erc-scenarios-base-reuse-buffers.el35
-rw-r--r--test/lisp/erc/erc-tests.el2
-rw-r--r--test/lisp/erc/resources/base/assoc/samenet/chester.eld2
-rw-r--r--test/lisp/erc/resources/base/assoc/samenet/tester.eld2
-rw-r--r--test/lisp/erc/resources/base/assoc/samenet/tester2.eld2
-rw-r--r--test/lisp/erc/resources/base/netid/samenet/chester.eld2
-rw-r--r--test/lisp/erc/resources/base/netid/samenet/tester.eld2
-rw-r--r--test/lisp/erc/resources/erc-d/erc-d-tests.el6
-rw-r--r--test/lisp/eshell/esh-var-tests.el12
-rw-r--r--test/lisp/filenotify-tests.el135
-rw-r--r--test/lisp/format-spec-tests.el11
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/0062E2DBC6D6848AE88BCE181CC1938F2FAC816C.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/02089CDDC6DFE93B8EA10D9E876F983E61FEC476.keybin797 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/052E3324B4811A197A1DE922671AA6ABE475025E.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/066DBED74BA05B5AA1E2A6E4634EF6F62C0D7A5F.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/0B0D8E451BFADF816524AF5E185EBF3DED48CA00.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/171B444DE92BEF997229000D9784118A94EEC1C9.keybin526 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/1967CB6C7B1C00996FCFF5930C3467D3D4FB702C.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/19FFEBC04DF3E037E16F6A4474DCB7984406975D.keybin841 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/1E36D27DF9DAB96302D35268DADC5CE73EF45A2A.keybin797 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/293109315BE584AB2EFEFCFCAD64666221D8B36C.keybin526 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/2C9A99AF2FB073D3328B0F995BD6DE74616A6CC2.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/3250B5BE67E704F82BC9AAE00EC8A0CAC8C2A94F.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/335689599E1C0F66D73ADCF51E03EE36C97D121F.keybin797 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/40BF94E540E3726CB150A1ADF7C1B514444B3FA6.keybin797 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/515D4637EFC6C09DB1F78BE8C2F2A3D63E7756C3.keybin798 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5294CDB62DB28FBB486DE077DAF248FB32BE286A.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5A11B1935C46D0B227A73978DCA1293A85604F1D.keybin798 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5B2B6633E89C0BD58A0FA2C785A31EAA96278695.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/61F5836DA69D9F63059D2665451F18E4346DF43A.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/62643CEBC7AEBE6817577A34399483700D76BD64.keybin526 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/64CA92780975EEB798D2083FF25AFD43A4033DB7.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/6DF2D9DF7AED06F0524BEB642DF0FB48EFDBDB93.keybin798 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/78C17E134E86E691297F7B719B2F2CDF41976234.keybin527 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/7A788436224049A2FE1E446E16B70DB012C830BB.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/7F714F4D9D9676638214991E96D45704E4FFC409.keybin798 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/854752F5D8090CA36EFBDD79C72BDFF6FA2D1FF0.keybin526 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/8865328E25351B0D7697D4156A13497174F999D5.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/9504643B1FB8AAC7529134D1565DF8B4ECA01E35.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/A3BA94EAE83509CC90DB1B77B54A51959D8DABEA.keybin797 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/A6BC0634D18962998AB53A0134DD2AD0DC4E0782.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/AE6A24B17A8D0CAF9B7E000AA77F0B41D7BFFFCF.keybin841 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/BCFF2771AD5F49BEC185CDED47EC47D15550CB93.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C072AF82DCCCB9A7F1B85FFA10B802DC4ED16703.keybin841 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C36C6A8B40A2179CFE83CB0C2827358AB171CDFD.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C43E1A079B28DFAEBB39CBA01793BDE11EF4B490.keybin527 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CB5E00CE582C2645D2573FC16B2F14F85A7F47AA.keybin797 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CC68630A06B048F5A91136C162C7A3273E20DE6F.keybin710 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CF723A68027A82B538F04BF4A2A1323D1B3E095C.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/D6A2C195DEBA3506F0ECFBE3DDD7C57F6913DC7C.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/DB8C922A471E08FAF083EC2465AFB4063904C282.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/E0C3163E69C57319C6038F9EBE14F5D55DE553F7.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/E7E73903E1BF93481DE0E7C9769D6C31E1863CFF.keybin797 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/ECB164A45A1D5C5078508A9869DF6DB84DEA543B.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F0117468BE801ED4B81972E159A98FDD4814DCEC.keybin797 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F4C5EFD5779BE892CAFD5B721D68DED677C9B151.keybin841 -> 0 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F4E86D61A71E9CE6B0DBC65C5121846E542913B9.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/private-keys-v1.d/FE38C61A8DB32297C7C3C18E7A837D7B70263BC7.key5
-rw-r--r--test/lisp/gnus/mml-sec-resources/pubring.gpgbin13883 -> 11564 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/secring.gpgbin17362 -> 9315 bytes
-rw-r--r--test/lisp/gnus/mml-sec-resources/trustdb.gpgbin1880 -> 1680 bytes
-rw-r--r--test/lisp/gnus/mml-sec-tests.el86
-rw-r--r--test/lisp/help-tests.el6
-rw-r--r--test/lisp/image/image-dired-util-tests.el71
-rw-r--r--test/lisp/image/wallpaper-tests.el181
-rw-r--r--test/lisp/international/ucs-normalize-tests.el89
-rw-r--r--test/lisp/net/mailcap-tests.el4
-rw-r--r--test/lisp/net/puny-resources/IdnaTestV2.txt4
-rw-r--r--test/lisp/obsolete/thumbs-tests.el (renamed from test/lisp/thumbs-tests.el)0
-rw-r--r--test/lisp/pcomplete-tests.el100
-rw-r--r--test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl8
-rw-r--r--test/lisp/progmodes/cperl-mode-resources/cperl-indents.erts26
-rw-r--r--test/lisp/progmodes/cperl-mode-tests.el45
-rw-r--r--test/lisp/progmodes/hideshow-tests.el106
-rw-r--r--test/lisp/progmodes/python-tests.el174
-rw-r--r--test/lisp/progmodes/ruby-mode-resources/ruby.rb4
-rw-r--r--test/lisp/so-long-tests/so-long-tests-helpers.el12
-rw-r--r--test/lisp/subr-tests.el8
-rw-r--r--test/lisp/time-stamp-tests.el8
-rw-r--r--test/lisp/whitespace-tests.el31
-rw-r--r--test/lisp/xdg-tests.el10
-rw-r--r--test/manual/BidiCharacterTest.txt12
-rw-r--r--test/manual/image-circular-tests.el41
-rw-r--r--test/manual/image-tests.el28
-rw-r--r--test/src/comp-tests.el157
-rw-r--r--test/src/emacs-module-resources/mod-test.c1
-rw-r--r--test/src/eval-tests.el20
-rw-r--r--test/src/fns-tests.el106
-rw-r--r--test/src/image-tests.el4
-rw-r--r--test/src/lcms-tests.el2
-rw-r--r--test/src/sqlite-tests.el13
681 files changed, 20196 insertions, 7807 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index 84617a79807..f7c73031cc8 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -1,4 +1,4 @@
-;;; Directory Local Variables
+;;; Directory Local Variables -*- no-byte-compile: t; -*-
;;; For more information see (info "(emacs) Directory Variables")
((nil . ((tab-width . 8)
diff --git a/.gitignore b/.gitignore
index a1dd83ce871..3b965d62478 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,6 +58,7 @@ src/emacs-module.h
# C-level sources built by 'make'.
lib/alloca.h
+lib/assert.h
lib/byteswap.h
lib/dirent.h
lib/errno.h
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 00000000000..8454eb9154c
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,197 @@
+#
+# This list is used to fix a few misspelled names in various git
+# listings (e.g., "git log"). This can be used to fix incorrect
+# attribution, poor display, or names showing up more than once.
+# It also allows updating an old email addresses to a new one.
+#
+# See "man git-shortlog" for more information on the format.
+#
+# Keep file sorted using `M-x sort-lines'.
+#
+Aaron S. Hawley <aaron.s.hawley@gmail.com> <Aaron.Hawley@vtinfo.com>
+Aaron S. Hawley <aaron.s.hawley@gmail.com> <Aaron.S.Hawley@gmail.com>
+Aaron S. Hawley <aaron.s.hawley@gmail.com> <ashawley@burlingtontelecom.net>
+Alan Third <alan@idiocy.org>
+Alan Third <alan@idiocy.org> <alan@breton-build.holly.idiocy.org>
+Alan Third <alan@idiocy.org> Alan Third <address@hidden>
+Alan Third <alan@idiocy.org> bug-gnu-emacs@gnu.org <bug-gnu-emacs@gnu.org>
+Alex Harsanyi <AlexHarsanyi@gmail.com> <harsanyi@mac.com>
+Alexander Gramiak <agrambot@gmail.com>
+Amin Bandali <bandali@gnu.org> <mab@gnu.org>
+Andrea Corallo <akrl@sdf.org>
+Andrea Corallo <akrl@sdf.org> <akrl@sdf.com>
+Andrea Corallo <akrl@sdf.org> <andcor03@e112547.nice.arm.com>
+Andrea Corallo <akrl@sdf.org> <andrea_corallo@yahoo.it>
+Andrew G Cohen <cohen@andy.bu.edu>
+Andrew G Cohen <cohen@andy.bu.edu> <cohen@bu.edu>
+Arash Esbati <arash@gnu.org> <arash.esbati@gmail.com>
+Arash Esbati <arash@gnu.org> <esbati@gmx.de>
+Artur Malabarba <bruce.connor.am@gmail.com> <am12548@it055607.users.bris.ac.uk>
+Bastien Guerry <bzg@gnu.org>
+Bastien Guerry <bzg@gnu.org> <bastien1@free.fr>
+Bastien Guerry <bzg@gnu.org> <bzg@altern.org>
+Benjamin Schwerdtner <Benjamin.Schwerdtner@gmail.com>
+Bob Rogers <rogers@rgrjr.com> <rogers-emacs@rgrjr.homedns.org>
+Bruno Félix Rezende Ribeiro <oitofelix@gnu.org> <oitofelix@gmail.com>
+Carlos Pita <carlosjosepita@gmail.com>
+Chong Yidong <cyd@gnu.org> <cyd@stupidchicken.com>
+Christoph Scholtes <cschol2112@gmail.com>
+Christoph Scholtes <cschol2112@gmail.com> <cschol2112@googlemail.com>
+Christoph Scholtes <cschol2112@gmail.com> Christoph Scholtes <>
+Clément Pit-Claudel <clement.pitclaudel@live.com>
+Clément Pit-Claudel <clement.pitclaudel@live.com> <clement.pit@gmail.com>
+Courtney Bane <emacs-bugs-7626@cbane.org>
+Daiki Ueno <ueno@gnu.org> <ueno@unixuser.org>
+Daiki Ueno <ueno@gnu.org> Daiki Ueno <ueno@debian>
+Dan Nicolaescu <dann@ics.uci.edu> <dann@gnu.org>
+Dan Nicolaescu <dann@ics.uci.edu> <done@ece.arizona.edu>
+Daniel Colascione <dancol@dancol.org> <dan.colascione@gmail.com>
+David Abrahams <dave@boostpro.com>
+David M. Koppelman <koppel@ece.lsu.edu>
+Deniz Dogan <deniz@dogan.se> <deniz.a.m.dogan@gmail.com>
+Dick R. Chiang <dick.r.chiang@gmail.com>
+Dick R. Chiang <dick.r.chiang@gmail.com> dickmao <none>
+Earl Hyatt <ej32u@protonmail.com>
+Earl Hyatt <ej32u@protonmail.com> <okamsn@protonmail.com>
+Edward M. Reingold <reingold@emr.cs.iit.edu>
+Eli Zaretskii <eliz@gnu.org> <eliz@is.elta.co.il>
+Emilio C. Lopes <eclig@gmx.net>
+Enami Tsugutomo <tsugutomo.enami@jp.sony.com>
+Era Eriksson <era+emacs@iki.fi> <era+emacsbugs@iki.fi>
+Eric Ludlam <zappo@gnu.org>
+Eric Ludlam <zappo@gnu.org> <eric@siege-engine.com>
+Eric Ludlam <zappo@gnu.org> <ericludlam@gmail.com>
+Eric S. Raymond <esr@thyrsus.com> <esr@snark.thyrsus.com>
+Etienne Prud’homme <e.e.f.prudhomme@gmail.com>
+Fabián Ezequiel Gallina <fgallina@gnu.org> <fgallina@cuca>
+Fabián Ezequiel Gallina <fgallina@gnu.org> <galli.87@gmail.com>
+Francis Litterio <flitterio@gmail.com>
+Gabor Vida <vidagabor@gmail.com>
+Gerd Möllmann <gerd@gnu.org>
+Gerd Möllmann <gerd@gnu.org> <gerd.moellmann@gmail.com>
+Glenn Morris <rgm@gnu.org>
+Glenn Morris <rgm@gnu.org> <rgm@fencepost>
+Glenn Morris <rgm@gnu.org> <rgm@stanford.edu>
+Gnus developers <ding@gnus.org.noreply> <ding@gnus.org>
+Gregory Heytings <gregory@heytings.org> <ghe@sdf.org>
+Grégoire Jadi <daimrod@gmail.com>
+Ian Dunn <dunni@gnu.org>
+Jan Djärv <jan.h.d@swipnet.se>
+Jan Djärv <jan.h.d@swipnet.se> <jhd@f20.localdomain>
+Jason Rumney <jasonr@gnu.org> <jasonr@wanchan>
+Jeff Walsh <fejfighter@gmail.com> <jawalsh@localhost.localdomain>
+Jeff Walsh <fejfighter@gmail.com> <jeff.walsh@drtusers-MacBook-Pro.local>
+Jeff Walsh <fejfighter@gmail.com> <jewalsh@redhat.com>
+Jens Lechtenbörger <jens.lechtenboerger@fsfe.org>
+Jim Blandy <jimb@red-bean.com> <jimb@redhat.com>
+Jimmy Aguilar Mena <spacibba@aol.com>
+Joakim Verona <joakim@verona.se>
+Joakim Verona <joakim@verona.se> <root@exodia.verona.se>
+John Wiegley <johnw@newartisans.com> <jwiegley@gmail.com>
+Jose A. Ortega Ruiz <jao@gnu.org>
+João Távora <joaotavora@gmail.com>
+Julien Danjou <julien@danjou.info> <jd@dex.adm.naquadah.org>
+Julien Danjou <julien@danjou.info> Julien Danjou <jd@abydos>
+Juri Linkov <juri@linkov.net> <juri@jurta.org>
+Jérémy Compostella <jeremy.compostella@gmail.com>
+Jürgen Hötzel <juergen@archlinux.org>
+Karl Fogel <kfogel@red-bean.com> <karl.fogel@canonical.com>
+Katsumi Yamaoka <yamaoka@jpl.org> <katsumi@flagship2>
+Kaushal Modi <kaushal.modi@gmail.com>
+Kelvin White <kwhite@gnu.org>
+Kelvin White <kwhite@gnu.org> <kelvin.white77@gmail.com>
+Ken Raeburn <raeburn@raeburn.org> <raeburn@permabit.com>
+Kenichi Handa <handa@gnu.org>
+Kenichi Handa <handa@gnu.org> <handa@etlken>
+Kenichi Handa <handa@gnu.org> <handa@m17n.org>
+Kenjiro Nakayama <nakayamakenjiro@gmail.com>
+Kjartan Óli Ágústsson <kjartanoli@outlook.com>
+Károly Lőrentey <lorentey@elte.hu>
+Lars Ingebrigtsen <larsi@gnus.org>
+Lars Ingebrigtsen <larsi@gnus.org> <larsi@emkay.local>
+Lars Ingebrigtsen <larsi@gnus.org> <larsi@openbsd6.gnus.org>
+Lars Ingebrigtsen <larsi@gnus.org> <larsi@quimbies.gnus.org>
+Lars Ingebrigtsen <larsi@gnus.org> <larsi@stories.gnus.org>
+Laurence Warne <laurencewarne@gmail.com>
+Lin Sun <lin.sun@zoom.us>
+Ludovic Courtès <ludo@gnu.org>
+Luke Lee <luke.yx.lee@gmail.com>
+Martin Rudalics <rudalics@gmx.at>
+Martin Rudalics <rudalics@gmx.at> <“rudalics@gmx.at”>
+Masatake YAMATO <yamato@redhat.com> <jet@gyve.org>
+Matt Armstrong <matt@rfc20.org> <marmstrong@google.com>
+Matt Armstrong <matt@rfc20.org> <matt@mdeb>
+Mattias Engdegård <mattiase@acm.org>
+Maxim Nikulin <manikulin@gmail.com>
+Michael Albinus <michael.albinus@gmx.de> <albinus@detlef>
+Michalis V <mvar.40k@gmail.com>
+Miha Rihtaršič <miha@kamnitnik.top>
+Morgan J. Smith <Morgan.J.Smith@outlook.com>
+Nick Drozd <nicholasdrozd@gmail.com>
+Nicolas Petton <nicolas@petton.fr> <petton.nicolas@gmail.com>
+Nitish Chandra <nitishchandrachinta@gmail.com>
+Noam Postavsky <npostavs@gmail.com> <npostavs@users.sourceforge.net>
+Noam Postavsky <npostavs@gmail.com> <npostavs@users.sourceforget.net>
+Paul Eggert <eggert@cs.ucla.edu> <eggert@Penguin.CS.UCLA.EDU>
+Paul Eggert <eggert@cs.ucla.edu> <eggert@day>
+Paul Eggert <eggert@cs.ucla.edu> <eggert@twinsun.com>
+Paul Eggert <eggert@cs.ucla.edu> <eggert@union>
+Peter J. Weisberg <pj@irregularexpressions.net>
+Peter Oliver <p.d.oliver@mavit.org.uk> <bzr@mavit.org.uk>
+Peter Oliver <p.d.oliver@mavit.org.uk> <git@mavit.org.uk>
+Philip Kaludercic <philipk@posteo.net>
+Philip Kaludercic <philipk@posteo.net> <philip.kaludercic@fau.de>
+Philip Kaludercic <philipk@posteo.net> <philip@icterid>
+Philip Kaludercic <philipk@posteo.net> <philip@warpmail.net>
+Philipp Stephani <phst@google.com>
+Philipp Stephani <phst@google.com> Philipp Stephani <p.stephani2@gmail.com>
+Phillip Lord <phillip.lord@russet.org.uk> <phillip.lord@newcastle.ac.uk>
+Pierre Lorenzon <devel@pollock-nageoire.net>
+Pieter van Oostrum <pieter@vanoostrum.org> <pieter-l@vanoostrum.org>
+Pip Cet <pipcet@gmail.com>
+Po Lu <luangruo@yahoo.com>
+Po Lu <luangruo@yahoo.com> Po Lu via <emacs-devel@gnu.org>
+Przemysław Wojnowski <esperanto@cumego.com>
+Rasmus <rasmus@gmx.us>
+Richard M. Stallman <rms@gnu.org>
+Robert J. Chassell <bob@gnu.org> <bob@rattlesnake.com>
+Robert Weiner <rsw@gnu.org> <rswgnu@gmail.com>
+Roland Winkler <winkler@gnu.org> <Roland.Winkler@physik.uni-erlangen.de>
+Ronnie Schnell <ronnie@driver-aces.com>
+Ryan C. Thompson <rct@thompsonclan.org>
+Sam Steingold <sds@gnu.org> <sdsg@amazon.com>
+Simen Heggestøyl <simenheg@runbox.com>
+Simen Heggestøyl <simenheg@runbox.com> <simenheg@ifi.uio.no>
+Simen Heggestøyl <simenheg@runbox.com> <simenheg@gmail.com>
+Simon Josefsson <simon@josefsson.org> <jas@extundo.com>
+Stefan Kangas <stefankangas@gmail.com> <stefan@marxist.se>
+Stefan Monnier <monnier@iro.umontreal.ca> <monnier@IRO.UMontreal.CA>
+Stephen Berman <stephen.berman@gmx.net> <Stephen.Berman@gmx.net>
+Stephen Berman <stephen.berman@gmx.net> <Stephen.Berman@gmx.net>
+Stephen Berman <stephen.berman@gmx.net> <steve@rosalinde.fritz.box>
+Stephen Gildea <stepheng+emacs@gildea.com>
+Stephen Gildea <stepheng+emacs@gildea.com> <gildea@stop.mail-abuse.org>
+Stephen Gildea <stepheng+emacs@gildea.com> <stepheng+git-config-global@gildea.com>
+Stephen Gildea <stepheng+emacs@gildea.com> <stepheng+savannah@gildea.com>
+Tassilo Horn <tsdh@gnu.org> <tassilo@member.fsf.org>
+Ted Zlatanov <tzz@lifelogs.com>
+Thien-Thi Nguyen <ttn@gnu.org> <ttn@gnuvola.org>
+Thierry Volpiatto <thievol@posteo.net> <thierry.volpiatto@gmail.com>
+Tino Calancha <ccalancha@suse.com> <f92capac@gmail.com>
+Tino Calancha <ccalancha@suse.com> <tino.calancha@gmail.com>
+Tom Tromey <tom@tromey.com> <tromey@redhat.com>
+Ulf Jasper <ulf.jasper@web.de> Ulf Jasper <>
+Ulf Jasper <ulf.jasper@web.de> Ulf Jasper <ulf@uthinkpad>
+Ulrich Müller <ulm@gentoo.org>
+Vinicius Jose Latorre <viniciusjl@ig.com.br> <viniciusjl.gnu@gmail.com>
+Vladimir Nikishkin <lockywolf@gmail.com> <for.emacs-table.el-environment-patch_2022-05-09@lockywolf.net>
+Werner Lemberg <wl@gnu.org>
+Wolfgang Scherer <wolfgang.scherer@gmx.de> <Wolfgang.Scherer@gmx.de>
+Xi Lu <lx@shellcodes.org>
+Xue Fuqiao <xfq.free@gmail.com> <xfq@gnu.org>
+Yilkal Argaw <yilkalargawworkneh@gmail.com>
+Yuuki Harano <masm+github@masm11.me> <masm@masm11.ddo.jp>
+Óscar Fuentes <ofv@wanadoo.es>
+İ. Göktuğ Kayaalp <self@gkayaalp.com>
+Łukasz Stelmach <stlman@poczta.fm> <l.stelmach@samsung.com>
+Łukasz Stelmach <stlman@poczta.fm> <lukasz.stelmach@iem.pw.edu.pl>
diff --git a/ChangeLog.1 b/ChangeLog.1
index cd31aacafb4..35533d60fff 100644
--- a/ChangeLog.1
+++ b/ChangeLog.1
@@ -5685,7 +5685,7 @@
(__mktime_internal): Use it systematically for all isdst comparisons.
This completes the fix for libc BZ #6723, and removes the need for
normalizing tm_isdst.
- See <http://sourceware.org/bugzilla/show_bug.cgi?id=6723>
+ See <https://sourceware.org/bugzilla/show_bug.cgi?id=6723>
(not_equal_tm) [DEBUG]: Use isdst_differ here, too.
mktime: fix some integer overflow issues and sidestep the rest
diff --git a/ChangeLog.3 b/ChangeLog.3
index a09dc29cbec..f2245a4ed53 100644
--- a/ChangeLog.3
+++ b/ChangeLog.3
@@ -185373,7 +185373,7 @@
* lisp/image.el (image-type-header-regexps):
Allow two or more CRs or LFs in initial whitespace sequences. See:
- http://netpbm.sourceforge.net/doc/pbm.html
+ https://netpbm.sourceforge.net/doc/pbm.html
2017-10-16 Paul Eggert <eggert@cs.ucla.edu>
@@ -197097,7 +197097,7 @@
Clang on macOS warns about these with -Wtautological-compare. POSIX
guarantees that rlim_t is
unsigned (cf.
- http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/resource.h.html),
+ https://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/resource.h.html),
so these resource limits can never be negative.
* src/emacs.c (main): Remove tautological comparisons.
@@ -199197,7 +199197,7 @@
' is commonly used as an apostrophe in the prose sections of spec
files, which was erroneously highlighted as strings. See for example
- http://kmymoney2.sourceforge.net/phb/rpm-example.html
+ https://kmymoney2.sourceforge.net/phb/rpm-example.html
* lisp/progmodes/sh-script.el (sh-mode-syntax-table): Treat ' as
punctuation in RPM spec files.
diff --git a/GNUmakefile b/GNUmakefile
index 8eb61dc0ad5..05edbe099b0 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -115,7 +115,7 @@ endif
# 'make bootstrap' in a fresh checkout needn't run 'configure' twice.
bootstrap: Makefile
- $(MAKE) -f Makefile all
+ $(MAKE) -f Makefile bootstrap-all
.PHONY: bootstrap default $(ORDINARY_GOALS)
diff --git a/INSTALL b/INSTALL
index 95d2dbda80c..c0323f770ba 100644
--- a/INSTALL
+++ b/INSTALL
@@ -187,7 +187,7 @@ X11 is being used.
libz (for PNG): https://www.zlib.net/
X libjpeg for JPEG: https://www.ijg.org/
X libtiff for TIFF: http://www.simplesystems.org/libtiff/
- X libgif for GIF: http://giflib.sourceforge.net/
+ X libgif for GIF: https://giflib.sourceforge.net/
librsvg2 for SVG: https://wiki.gnome.org/Projects/LibRsvg
libwebp for WebP: https://developers.google.com/speed/webp/
diff --git a/Makefile.in b/Makefile.in
index d288bacb9dd..45b4a59e3db 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -52,14 +52,14 @@
# make bootstrap
# Removes all the compiled files to force a new bootstrap from a
# clean slate, and then build in the normal way. If the FAST Make
-# variable is set, then the config.cache file isn't removed. This
-# allows you to say
+# variable is set, then the autom4te.cache directory and the
+# config.cache file are not removed. This lets you say
#
# ./configure -C
# make FAST=true bootstrap
#
# and use the cached results from the configure run, which is much
-# faster.
+# faster though it does not work in general.
#
# make docs
# Make Emacs documentation files from their sources; requires makeinfo.
@@ -366,7 +366,67 @@ endif
gsettings_SCHEMAS = etc/org.gnu.emacs.defaults.gschema.xml
-all: ${SUBDIR} info $(gsettings_SCHEMAS:.xml=.valid) src-depending-on-lisp
+all:
+ $(MAKE) actual-all || $(MAKE) advice-on-failure make-target=all exit-status=$$?
+ $(MAKE) sanity-check make-target=all
+
+# This target is used by the 'bootstrap' target in GNUmakefile, instead of 'all'.
+bootstrap-all:
+ $(MAKE) actual-all || $(MAKE) advice-on-failure make-target=bootstrap exit-status=$$?
+ $(MAKE) sanity-check make-target=bootstrap
+
+.PHONY: bootstrap-all actual-all advice-on-failure sanity-check
+
+actual-all: ${SUBDIR} info $(gsettings_SCHEMAS:.xml=.valid) src-depending-on-lisp
+
+# ADVICE-ON-FAILURE-BEGIN:all
+# You could try to:
+# - run "make bootstrap", which might fix the problem
+# - run "make V=1", which displays the full commands invoked by make,
+# to further investigate the problem
+# ADVICE-ON-FAILURE-END:all
+
+# ADVICE-ON-FAILURE-BEGIN:bootstrap
+# You could try to:
+# - run "make extraclean" and run "make" again (or, equivalently, run
+# "make bootstrap configure=default"), to rebuild Emacs with the
+# default configuration options, which might fix the problem
+# - run "git clean -fdx" and run "make bootstrap" again, which might
+# fix the problem if "make bootstrap configure=default" did not
+# !BEWARE! "git clean -fdx" deletes all files that are not under
+# !BEWARE! version control, which means that all changes to such
+# !BEWARE! files will be lost and cannot be restored later
+# - run "make V=1", which displays the full commands invoked by make,
+# to further investigate the problem
+# - report the problem and ask for help by sending an email to
+# bug-gnu-emacs@gnu.org, mentioning at least the build error
+# message, the platform, and the repository revision displayed by
+# "git rev-parse HEAD"
+# ADVICE-ON-FAILURE-END:bootstrap
+
+advice-on-failure:
+ @echo >&2 '***'
+ @echo >&2 '*** '"\"make ${make-target}\" failed with exit status ${exit-status}."
+ @echo >&2 '***'
+ @cat Makefile | \
+ sed -n '/^# ADVICE-ON-FAILURE-BEGIN:${make-target}/,$${p;/^# ADVICE-ON-FAILURE-END:${make-target}/q};' | \
+ sed 's/^# /*** /' | grep -v '^*** ADVICE-ON-FAILURE-' >&2
+ @echo >&2 '***'
+ @exit ${exit-status}
+
+sanity-check:
+ @v=$$(src/emacs${EXEEXT} --batch --eval \
+ '(progn (defun f (n) (if (= 0 n) 1 (* n (f (- n 1))))) (princ (f 10)))' \
+ 2> /dev/null); \
+ [ "X$$v" = "X3628800" ] && exit 0; \
+ echo >&2 '***'; \
+ echo >&2 '*** '"\"make ${make-target}\" succeeded, but Emacs is not functional."; \
+ echo >&2 '***'; \
+ cat Makefile | \
+ sed -n '/^# ADVICE-ON-FAILURE-BEGIN:${make-target}/,$${p;/^# ADVICE-ON-FAILURE-END:${make-target}/q};' | \
+ sed 's/^# /*** /' | grep -v '^*** ADVICE-ON-FAILURE-' >&2; \
+ echo >&2 '***'; \
+ exit 1
.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 epaths-force-ns-self-contained etc-emacsver
@@ -470,6 +530,11 @@ lisp: src
lib lib-src lisp nt: Makefile
$(MAKE) -C $@ all
+trampolines: src lisp
+ifeq ($(HAVE_NATIVE_COMP),yes)
+ $(MAKE) -C lisp trampolines
+endif
+
# Pass an unexpanded $srcdir to src's Makefile, which then
# expands it using its own value of srcdir (which points to the
# source directory of src/).
@@ -522,7 +587,7 @@ $(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/m4/*.m4
## don't have to duplicate the list of utilities to install in
## this Makefile as well.
-install: all install-arch-indep install-etcdoc install-arch-dep install-$(NTDIR) blessmail install-eln install-gsettings-schemas
+install: actual-all install-arch-indep install-etcdoc install-arch-dep install-$(NTDIR) blessmail install-eln install-gsettings-schemas
@true
## Ensure that $subdir contains a subdirs.el file.
@@ -638,8 +703,8 @@ install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
[ -d $${dir} ] || exit 1 ; \
dest="$$1" ; shift ; \
if [ -d "$${dest}" ]; then \
- exp_dest=`cd "$${dest}" && /bin/pwd`; \
- [ "$$exp_dest" = "`cd $${dir} && /bin/pwd`" ] && continue ; \
+ exp_dest=`cd "$${dest}" && pwd -P`; \
+ [ "$$exp_dest" = "`cd $${dir} && pwd -P`" ] && continue ; \
else true; \
fi; \
rm -rf "$${dest}" ; \
@@ -695,8 +760,8 @@ install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
install-etcdoc: src install-arch-indep
-unset CDPATH; \
umask 022; ${MKDIR_P} "$(DESTDIR)${etcdocdir}" ; \
- exp_etcdocdir=`cd "$(DESTDIR)${etcdocdir}"; /bin/pwd`; \
- if [ "`cd ./etc; /bin/pwd`" != "$$exp_etcdocdir" ]; \
+ exp_etcdocdir=`cd "$(DESTDIR)${etcdocdir}"; pwd -P`; \
+ if [ "`cd ./etc; pwd -P`" != "$$exp_etcdocdir" ]; \
then \
docfile="DOC"; \
printf 'Copying %s to %s ...\n' "etc/$$docfile" \
@@ -711,9 +776,9 @@ install-etcdoc: src install-arch-indep
install-info: info
umask 022; ${MKDIR_P} "$(DESTDIR)${infodir}"
-unset CDPATH; \
- thisdir=`/bin/pwd`; \
- exp_infodir=`cd "$(DESTDIR)${infodir}" && /bin/pwd`; \
- if [ "`cd ${srcdir}/info && /bin/pwd`" = "$$exp_infodir" ]; then \
+ thisdir=`pwd -P`; \
+ exp_infodir=`cd "$(DESTDIR)${infodir}" && pwd -P`; \
+ if [ "`cd ${srcdir}/info && pwd -P`" = "$$exp_infodir" ]; then \
true; \
else \
[ -f "$(DESTDIR)${infodir}/dir" ] || \
@@ -742,7 +807,7 @@ install-info: info
## but not sure if portable.
install-man:
umask 022; ${MKDIR_P} "$(DESTDIR)${man1dir}"
- thisdir=`/bin/pwd`; \
+ thisdir=`pwd -P`; \
cd ${mansrcdir}; \
for page in *.1; do \
test "$$page" = ChangeLog.1 && continue; \
@@ -809,7 +874,7 @@ install-etc:
${srcdir}/etc/emacs.service > $${tmp}; \
$(INSTALL_DATA) $${tmp} "$(DESTDIR)$(systemdunitdir)/${EMACS_NAME}.service"; \
rm -f $${tmp}
- thisdir=`/bin/pwd`; \
+ thisdir=`pwd -P`; \
cd ${iconsrcdir} || exit 1; umask 022 ; \
for dir in */*/apps */*/mimetypes; do \
[ -d $${dir} ] || continue ; \
@@ -844,10 +909,10 @@ uninstall: uninstall-$(NTDIR) uninstall-doc uninstall-gsettings-schemas
rm -f "$(DESTDIR)$(includedir)/emacs-module.h"
$(MAKE) -C lib-src uninstall
-unset CDPATH; \
- for dir in "$(DESTDIR)${lispdir}" "$(DESTDIR)${etcdir}" ; do \
+ for dir in "$(DESTDIR)${lispdir}" "$(DESTDIR)${etcdir}" "$(ELN_DESTDIR)" ; do \
if [ -d "$${dir}" ]; then \
- case `cd "$${dir}" ; /bin/pwd` in \
- "`cd ${srcdir} ; /bin/pwd`"* ) ;; \
+ case `cd "$${dir}" ; pwd -P` in \
+ "`cd ${srcdir} ; pwd -P`"* ) ;; \
* ) rm -rf "$${dir}" ;; \
esac ; \
case "$${dir}" in \
@@ -858,7 +923,7 @@ uninstall: uninstall-$(NTDIR) uninstall-doc uninstall-gsettings-schemas
fi ; \
done
-rm -rf "$(DESTDIR)${libexecdir}/emacs/${version}"
- thisdir=`/bin/pwd`; \
+ thisdir=`pwd -P`; \
(info_misc=`MAKEFLAGS= $(MAKE) --no-print-directory -s -C doc/misc echo-info`; \
if cd "$(DESTDIR)${infodir}"; then \
for elt in ${INFO_NONMISC} $${info_misc}; do \
@@ -975,7 +1040,7 @@ bootstrap-clean: $(distclean_dirs:=_bootstrap-clean)
rm -f ${srcdir}/etc/refcards/emacsver.tex
rm -rf native-lisp/ lisp/leim/ja-dic/
ifndef FAST
- rm -f config.cache
+ rm -fr autom4te.cache config.cache
endif
${top_bootclean}
@@ -1170,7 +1235,11 @@ check-info: info
### This first cleans the lisp subdirectory, removing all compiled
### Lisp files. Then re-run make to build all the files anew.
-.PHONY: bootstrap
+.PHONY: bootstrap actual-bootstrap
+
+bootstrap:
+ $(MAKE) actual-bootstrap || $(MAKE) advice-on-failure make-target=bootstrap exit-status=$$?
+ $(MAKE) sanity-check make-target=bootstrap
# Without a 'configure' variable, bootstrapping does the following:
# * Remove files to start from a bootstrap-clean slate.
@@ -1181,7 +1250,7 @@ check-info: info
# * Remove files to start from an extraclean slate.
# * Do the actual build, during which the 'configure' variable is
# used (see the Makefile goal in GNUmakefile).
-bootstrap:
+actual-bootstrap:
ifndef configure
$(MAKE) bootstrap-clean
cd $(srcdir) && ./autogen.sh autoconf
@@ -1189,7 +1258,7 @@ ifndef configure
else
$(MAKE) extraclean
endif
- $(MAKE) all
+ $(MAKE) actual-all
.PHONY: ChangeLog change-history change-history-commit change-history-nocommit
.PHONY: preferred-branch-is-current unchanged-history-files
diff --git a/admin/admin.el b/admin/admin.el
index fececc86a4b..6a67f172e2c 100644
--- a/admin/admin.el
+++ b/admin/admin.el
@@ -778,6 +778,204 @@ Optional argument TYPE is type of output (nil means all)."
(if (member type (list nil m))
(make-manuals-dist--1 root m))))
+(defvar admin--org-export-headers-format "\
+#+title: GNU Emacs %s NEWS -- history of user-visible changes
+#+author:
+#+options: author:nil creator:nil toc:2 num:3 *:nil \\n:t ^:nil tex:nil
+#+language: en
+#+HTML_LINK_HOME: /software/emacs
+#+HTML_LINK_UP: /software/emacs
+#+html_head_extra: <link rel=\"stylesheet\" type=\"text/css\" href=\"/mini.css\" media=\"handheld\" />
+#+html_head_extra: <link rel=\"stylesheet\" type=\"text/css\" href=\"/layout.min.css\" media=\"screen\" />
+#+html_head_extra: <link rel=\"stylesheet\" type=\"text/css\" href=\"/print.min.css\" media=\"print\" />
+
+#+BEGIN_EXPORT html
+<div style=\"float:right;margin-left:1em;padding:3px;border:0px solid;text-align:center\">
+<a href=\"/graphics/gnu-head.jpg\">
+<img src=\"/graphics/gnu-head-sm.jpg\" alt=\" [image of the head
+of a GNU] \" width=\"129\" height=\"122\"/>
+</a>
+</div>
+#+END_EXPORT\n\n")
+
+(defvar admin--org-html-postamble "
+<p>
+Return to the <a href=\"/software/emacs/emacs.html\">GNU Emacs home page</a>.
+</p>
+
+<div id=\"footer\">
+<div class=\"unprintable\">
+
+<p>
+Please send FSF &amp; GNU inquiries to
+<a href=\"mailto:gnu@gnu.org\">&lt;gnu@gnu.org&gt;</a>.
+There are also <a href=\"/contact/\">other ways to contact</a>
+the FSF.
+Broken links and other corrections or suggestions can be sent to
+<a href=\"mailto:bug-gnu-emacs@gnu.org\">&lt;bug-gnu-emacs@gnu.org&gt;</a>.
+</p>
+</div>
+
+<p>
+ Copyright &copy; %s Free Software Foundation, Inc.
+</p>
+
+<p>This page is licensed under
+a <a href=\"https://creativecommons.org/licenses/by-sa/4.0\">CC-BY-SA</a>
+license.</p>
+
+<!--#include virtual=\"/server/bottom-notes.html\" -->
+
+<p class=\"unprintable\">
+Updated:
+<!-- timestamp start -->
+$Date: %s $
+<!-- timestamp end -->
+</p>
+</div>
+</div>")
+
+(defun admin--require-external-package (pkg)
+ (package-initialize)
+ (require pkg nil t)
+ (unless (featurep pkg)
+ (when (yes-or-no-p (format "Package \"%s\" is missing. Install now?" pkg))
+ (package-install pkg)
+ (require pkg nil t))))
+
+(defvar org-html-postamble)
+(defvar org-html-mathjax-template)
+(defun make-news-html-file (root version)
+ "Convert the NEWS file into an HTML file."
+ (interactive (let ((root
+ (if noninteractive
+ (or (pop command-line-args-left)
+ default-directory)
+ (read-directory-name "Emacs root directory: "
+ source-directory nil t))))
+ (list root
+ (read-string "Major version number: "
+ (number-to-string emacs-major-version)))))
+ (unless (file-exists-p (expand-file-name "src/emacs.c" root))
+ (user-error "%s doesn't seem to be the root of an Emacs source tree" root))
+ (admin--require-external-package 'htmlize)
+ (let* ((newsfile (expand-file-name "etc/NEWS" root))
+ (orgfile (expand-file-name (format "etc/NEWS.%s.org" version) root))
+ (html (format "%s.html" (file-name-base orgfile)))
+ (copyright-years (format-time-string "%Y")))
+ (delete-file orgfile)
+ (copy-file newsfile orgfile t)
+ (find-file orgfile)
+
+ ;; Find the copyright range.
+ (goto-char (point-min))
+ (re-search-forward "^Copyright (C) \\([0-9-]+\\) Free Software Foundation, Inc.")
+ (setq copyright-years (match-string 1))
+
+ ;; Delete some unnecessary stuff.
+ (replace-regexp-in-region "^---$" "" (point-min) (point-max))
+ (replace-regexp-in-region "^\\+\\+\\+$" "" (point-min) (point-max))
+ (dolist (str '(" \n"
+ "GNU Emacs NEWS -- history of user-visible changes."
+ "Temporary note:"
+ "+++ indicates that all relevant manuals in doc/ have been updated."
+ "--- means no change in the manuals is needed."
+ "When you add a new item, use the appropriate mark if you are sure it"
+ "applies, and please also update docstrings as needed."
+ "You can narrow news to a specific version by calling 'view-emacs-news'"
+ "with a prefix argument or by typing 'C-u C-h C-n'."))
+ (replace-string-in-region str "" (point-min) (point-max)))
+
+ ;; Escape some characters.
+ (replace-regexp-in-region (rx "$") "@@html:&dollar;@@" (point-min) (point-max))
+
+ ;; Use Org-mode markers for 'symbols', 'C-x k', etc.
+ (replace-regexp-in-region
+ (rx (or (: (group (in " \t\n("))
+ "'"
+ (group (+ (or (not (in "'\n"))
+ (: "'" (not (in " .,\t\n)"))))))
+ "'"
+ (group (in ",.;:!? \t\n)")))
+ ;; Buffer names, e.g. "*scratch*".
+ (: "\""
+ (group-n 2 "*" (+ (not (in "*\""))) "*")
+ "\"")))
+ "\\1~\\2~\\3" (point-min) (point-max))
+
+ ;; Format code blocks.
+ (while (re-search-forward "^ " nil t)
+ (let ((elisp-block (looking-at "(")))
+ (backward-paragraph)
+ (insert (if elisp-block
+ "\n#+BEGIN_SRC emacs-lisp"
+ "\n#+BEGIN_EXAMPLE"))
+ (forward-paragraph)
+ (insert (if elisp-block
+ "#+END_SRC\n"
+ "#+END_EXAMPLE\n"))))
+
+ ;; Delete buffer local variables.
+ (goto-char (point-max))
+ (when (re-search-backward "Local variables:")
+ (forward-line -1)
+ (delete-region (point) (point-max)))
+
+ ;; Insert Org-mode export headers.
+ (goto-char (point-min))
+ (insert (format admin--org-export-headers-format version))
+ (org-mode)
+ (save-buffer)
+
+ ;; Make everything one level lower.
+ (goto-char (point-min))
+ (while (re-search-forward (rx bol (group (+ "*")) " ") nil t)
+ (replace-match "*\\1" nil nil nil 1))
+
+ ;; Insert anchors for different versions.
+ (goto-char (point-min))
+ (let (last-major last-minor)
+ (while (re-search-forward (rx bol "** " (+ (not "\n")) "in Emacs "
+ (group digit digit) "." (group digit)
+ eol)
+ nil t)
+ (unless (and (equal (match-string 1) last-major)
+ (equal (match-string 2) last-minor))
+ (setq last-major (match-string 1))
+ (setq last-minor (match-string 2))
+ (forward-line -1)
+ (insert (format
+ (concat
+ "#+HTML: <p>&nbsp;</p>\n"
+ "* Changes in Emacs %s.%s\n"
+ ;; Add anchor to allow linking to
+ ;; e.g. "NEWS.28.html#28.1".
+ ":PROPERTIES:\n"
+ ":CUSTOM_ID: %s.%s\n"
+ ":END:\n")
+ last-major last-minor
+ last-major last-minor)))))
+
+ (save-buffer)
+
+ ;; Make the HTML export.
+ (let* ((org-html-postamble
+ (format admin--org-html-postamble
+ copyright-years
+ ;; e.g. "2022/09/13 09:13:13"
+ (format-time-string "%Y/%m/%d %H:%m:%S")))
+ (org-html-mathjax-template "")
+ (htmlize-output-type 'css))
+ (org-html-export-as-html))
+
+ ;; Write HTML to file.
+ (let ((html (expand-file-name html (expand-file-name "etc" root))))
+ (write-file html)
+ (unless noninteractive
+ (find-file html)
+ (html-mode))
+ (message "Successfully exported HTML to %s" html))))
+
;; Stuff to check new `defcustom's got :version tags.
;; Adapted from check-declare.el.
diff --git a/admin/automerge b/admin/automerge
index 99191867367..c7c17dfb5ec 100755
--- a/admin/automerge
+++ b/admin/automerge
@@ -35,6 +35,8 @@
## it with the -d option in the repository directory, in case a pull
## updates this script while it is working.
+set -o nounset
+
die () # write error to stderr and exit
{
[ $# -gt 0 ] && echo "$PN: $*" >&2
diff --git a/admin/charsets/mapfiles/stdenc.txt b/admin/charsets/mapfiles/stdenc.txt
index e39486a3195..1c898bac0ba 100644
--- a/admin/charsets/mapfiles/stdenc.txt
+++ b/admin/charsets/mapfiles/stdenc.txt
@@ -54,7 +54,7 @@
#
# [v0.1, 5 May 1995] First release.
#
-# Use the Unicode reporting form <http://www.unicode.org/reporting.html>
+# Use the Unicode reporting form <https://www.unicode.org/reporting.html>
# for any questions or comments or to report errors in the data.
#
0020 20 # SPACE # space
diff --git a/admin/charsets/mapfiles/symbol.txt b/admin/charsets/mapfiles/symbol.txt
index b98baf6cf0c..0a5aac8b611 100644
--- a/admin/charsets/mapfiles/symbol.txt
+++ b/admin/charsets/mapfiles/symbol.txt
@@ -57,7 +57,7 @@
#
# [v0.1, 5 May 1995] First release.
#
-# Use the Unicode reporting form <http://www.unicode.org/reporting.html>
+# Use the Unicode reporting form <https://www.unicode.org/reporting.html>
# for any questions or comments or to report errors in the data.
#
0020 20 # SPACE # space
diff --git a/admin/emake b/admin/emake
index 8b2114b3f8c..e2f38501e93 100755
--- a/admin/emake
+++ b/admin/emake
@@ -20,7 +20,20 @@ if [ -f /proc/cpuinfo ]; then
sed 's/^[0-9]*/+/')))
fi
-make FAST=true -j$cores "$@" 2>&1 | \
+NOCOLOR=0
+NOCHECK=0
+FASTOPT="FAST=true"
+QUIETER=0
+while :
+do
+ [[ "X$1" == "X--no-color" ]] && { NOCOLOR=1; shift; continue; }
+ [[ "X$1" == "X--no-check" ]] && { NOCHECK=1; shift; continue; }
+ [[ "X$1" == "X--no-fast" ]] && { FASTOPT=""; shift; continue; }
+ [[ "X$1" == "X--quieter" ]] && { QUIETER=1; shift; continue; }
+ break
+done
+
+make $FASTOPT -j$cores "$@" 2>&1 | \
sed -u 's# \.\./\.\./# #
s# \.\./# #
s#^Configuring local git # Configuring local git #
@@ -30,6 +43,7 @@ s#^Configured for # Configured for #
s#^./temacs.*# \\& #
s#^make.*Error# \\& #
s#^Dumping under the name.*# \\& #
+:a;/\\$/N;s/\\\n//;ta
' | \
grep -E --line-buffered -v "^make|\
^Loading|\
@@ -82,16 +96,38 @@ The GNU allocators don't work|\
^\^\(\(|\
^ANCIENT=yes make|\
^touch -t|\
-^'build-aux/git-hooks\
+^'build-aux/git-hooks|\
+^GNUmakefile:[0-9]*: There seems to be no |\
+^GNUmakefile:[0-9]*: Running |\
+^GNUmakefile:[0-9]*: No Makefile|\
+^rm -f |\
+^rm -rf|\
+^find \. |\
+^rm -fr deps|\
+^if test -f \./\.gdbinit|\
+^true|\
+^for file in |\
+^rmdir|\
+^\[ \"\.\" = \"\.\" \]\
" | \
while read
do
C=""
- [[ "X${REPLY:0:1}" != "X " ]] && C="\033[1;31m"
- [[ "X${REPLY:0:3}" == "X " ]] && C="\033[1;31m"
- [[ "X$C" == "X" ]] && printf "%s\n" "$REPLY" || printf "$C%s\033[0m\n" "$REPLY"
+ (($NOCOLOR == 0)) && [[ "X${REPLY:0:1}" != "X " ]] && C="\033[1;31m"
+ (($NOCOLOR == 0)) && [[ "X${REPLY:0:3}" == "X " ]] && C="\033[1;31m"
+ if (($QUIETER == 0))
+ then
+ [[ "X$C" == "X" ]] && printf "%s\n" "$REPLY" || printf "$C%s\033[0m\n" "$REPLY"
+ else
+ [[ "X$C" == "X" ]] && printf "%-80s\r" "$REPLY" || printf "$C%-80s\033[0m\n" "$REPLY"
+ fi
done
+# If make failed, exit now with its error code.
+((${PIPESTATUS[0]} != 0)) && exit ${PIPESTATUS[0]}
+
+(($NOCHECK == 1)) && exit 0
+
# Run a "make check" on all test files belonging to files that have
# changed since last time.
make -j$cores check-maybe 2>&1 | \
diff --git a/admin/gitmerge.el b/admin/gitmerge.el
index 25bed949ad9..ddd3e184424 100644
--- a/admin/gitmerge.el
+++ b/admin/gitmerge.el
@@ -97,11 +97,14 @@ If nil, the function `gitmerge-default-branch' guesses.")
(defvar gitmerge-mode-map
(let ((map (make-keymap)))
- (define-key map [(l)] 'gitmerge-show-log)
- (define-key map [(d)] 'gitmerge-show-diff)
- (define-key map [(f)] 'gitmerge-show-files)
- (define-key map [(s)] 'gitmerge-toggle-skip)
- (define-key map [(m)] 'gitmerge-start-merge)
+ (define-key map [(l)] #'gitmerge-show-log)
+ (define-key map [(d)] #'gitmerge-show-diff)
+ (define-key map [(f)] #'gitmerge-show-files)
+ (define-key map [(s)] #'gitmerge-toggle-skip)
+ (define-key map [(m)] #'gitmerge-start-merge)
+ ;; For convenience:
+ (define-key map [(n)] #'next-line)
+ (define-key map [(p)] #'previous-line)
map)
"Keymap for gitmerge major mode.")
@@ -631,12 +634,18 @@ Branch FROM will be prepended to the list."
(with-current-buffer
(gitmerge-setup-log-buffer gitmerge--commits gitmerge--from)
(goto-char (point-min))
- (insert (propertize "Commands: " 'font-lock-face 'bold)
- "(s) Toggle skip, (l) Show log, (d) Show diff, "
- "(f) Show files, (m) Start merge\n"
- (propertize "Flags: " 'font-lock-face 'bold)
- "(C) Detected backport (cherry-mark), (R) Matches skip "
- "regexp, (M) Manually picked\n\n")
+ (insert (substitute-command-keys
+ (concat
+ (propertize "Commands: " 'font-lock-face 'bold)
+ "\\<gitmerge-mode-map>"
+ "(\\[gitmerge-toggle-skip]) Toggle skip, "
+ "(\\[gitmerge-show-log]) Show log, "
+ "(\\[gitmerge-show-diff]) Show diff, "
+ "(\\[gitmerge-show-files]) Show files, "
+ "(\\[gitmerge-start-merge]) Start merge\n"
+ (propertize "Flags: " 'font-lock-face 'bold)
+ "(C) Detected backport (cherry-mark), (R) Matches skip "
+ "regexp, (M) Manually picked\n\n")))
(gitmerge-mode)
(pop-to-buffer (current-buffer))
(if noninteractive (gitmerge-start-merge))))))
diff --git a/admin/grammars/Makefile.in b/admin/grammars/Makefile.in
index 4ca88982cde..178c79b7a02 100644
--- a/admin/grammars/Makefile.in
+++ b/admin/grammars/Makefile.in
@@ -35,7 +35,7 @@ unexport EMACSDATA EMACSDOC EMACSLOADPATH EMACSPATH
EMACS = ${top_builddir}/src/emacs
emacs = "${EMACS}" -batch --no-site-file --no-site-lisp \
- --eval '(setq max-specpdl-size 5000)' --eval '(setq load-prefer-newer t)'
+ --eval '(setq load-prefer-newer t)'
make_bovine = ${emacs} -l semantic/bovine/grammar -f bovine-batch-make-parser
make_wisent = ${emacs} -l semantic/wisent/grammar -f wisent-batch-make-parser
diff --git a/admin/make-manuals b/admin/make-manuals
index 8085412cc8a..cb0c00a423f 100755
--- a/admin/make-manuals
+++ b/admin/make-manuals
@@ -33,6 +33,8 @@
### Code:
+set -o nounset
+
die () # write error to stderr and exit
{
[ $# -gt 0 ] && echo "$PN: $@" >&2
diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt
index a60fead2678..d881b816125 100644
--- a/admin/make-tarball.txt
+++ b/admin/make-tarball.txt
@@ -52,10 +52,12 @@ General steps (for each step, check for possible errors):
./autogen.sh
./configure --with-native-compilation && make
- For a release (as opposed to pretest), delete any left-over "---"
- and "+++" markers from etc/NEWS, as well as the "Temporary note"
- section at the beginning of that file, and commit etc/NEWS if it
- was modified.
+ For a release (as opposed to pretest), visit etc/NEWS and use the
+ "M-x emacs-news-delete-temporary-markers" command to delete any
+ left-over "---" and "+++" markers from etc/NEWS, as well as the
+ "Temporary note" section at the beginning of that file, and commit
+ etc/NEWS if it was modified. For a bug fix release (e.g. 28.2),
+ delete any empty headlines too.
2. Regenerate the versioned ChangeLog.N and etc/AUTHORS files.
@@ -118,12 +120,13 @@ General steps (for each step, check for possible errors):
Set the version number to that of the actual release (commit in
one, as described above). Pick a date about a week from now when
- you intend to make the release. Use M-x add-release-logs to add
- entries to etc/HISTORY and the ChangeLog file. It's best not to
- commit these files until the release is actually made. Merge the
- entries from (unversioned) ChangeLog into the top of the current
- versioned ChangeLog.N and commit that along with etc/HISTORY.
- Then you can tag that commit as the release.
+ you intend to make the release. Use M-x add-release-logs from
+ admin/admin.el to add entries to etc/HISTORY and the ChangeLog
+ file. It's best not to commit these files until the release is
+ actually made. Merge the entries from (unversioned) ChangeLog
+ into the top of the current versioned ChangeLog.N and commit that
+ along with etc/HISTORY. Then you can tag that commit as the
+ release.
Alternatively, you can commit and tag with the RC tag right away,
and delay the final tagging until you actually decide to make a
@@ -163,7 +166,10 @@ General steps (for each step, check for possible errors):
Commit ChangeLog.N, etc/AUTHORS, lisp/ldefs-boot.el, and the files
changed by M-x set-version. Note that the set-version changes
- should be committed separately, as described in step 3 above.
+ should be committed separately, as described in step 3 above, to
+ avoid them being merged to master. The lisp/ldefs-boot.el file
+ should not be merged to master either, so it could be added to the
+ same commit or committed separately.
The easiest way of doing that is "C-x v d ROOT-DIR RET", then go
to the first modified file, press 'M' to mark all modified files,
@@ -384,7 +390,7 @@ Next, regenerate the various manuals in HTML, PDF, and PS formats:
Now change to the 'manual' directory and invoke upload-manuals:
- ../admin/updload-manuals /path/to/webpages/cvs/checkout
+ ../admin/upload-manuals /path/to/webpages/cvs/checkout
where /path/to/webpages/cvs/checkout is the place where you have the
CVS checkout of the Emacs Web pages, with subdirectories 'manual'
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 4dd6a4d222f..d3c5520ad0f 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -43,7 +43,7 @@ GNULIB_MODULES='
nanosleep nproc nstrftime
pathmax pipe2 pselect pthread_sigmask
qcopy-acl readlink readlinkat regex
- sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stddef stdio
+ sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stdbool stddef stdio
stpcpy strnlen strtoimax symlink sys_stat sys_time
tempname time time_r time_rz timegm timer-time timespec-add timespec-sub
update-copyright unlocked-io utimensat
@@ -54,7 +54,7 @@ AVOIDED_MODULES='
btowc chmod close crypto/af_alg dup fchdir fstat langinfo lock
mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo
openat-die opendir pthread-h raise
- save-cwd select setenv sigprocmask stat stdarg stdbool
+ save-cwd select setenv sigprocmask stat stdarg
threadlib tzset unsetenv utime utime-h
wchar wcrtomb wctype-h
'
diff --git a/admin/notes/repo b/admin/notes/repo
index f6004a97db1..c2d7f993a02 100644
--- a/admin/notes/repo
+++ b/admin/notes/repo
@@ -124,6 +124,11 @@ This ChangeLog file is not put into the repository.
'make change-history' copies all newer ChangeLog entries into the
start of the newest ChangeLog history file. These ChangeLog entries
are thereafter considered to be old, so later uses of 'make ChangeLog'
-and/or 'make change-history' will no longer copy the entries. To
-alter ChangeLog history, run 'make change-history', then edit
-the ChangeLog history files manually and commit your changes.
+and/or 'make change-history' will no longer copy the entries.
+
+To alter ChangeLog history, run 'make change-history' and commit the
+changes made by that command. Then edit the ChangeLog history files
+manually and commit those changes in a second, distinct commit.
+Altering ChangeLog history like this can make things harder for those
+who handle merging branches and Emacs releases, so reserve it for
+correcting more serious mistakes.
diff --git a/admin/notes/unicode b/admin/notes/unicode
index f699f4fb1c0..014bfb9b0d5 100644
--- a/admin/notes/unicode
+++ b/admin/notes/unicode
@@ -103,6 +103,10 @@ modified to follow suit. If there's trailing whitespace in
BidiCharacterTest.txt, it should be removed before committing the new
version.
+src/macuvs.h is a generated file, but if it has changed as a result
+of the updates, please commit it as well (see
+admin/unidata/Makefile.in for an explanation).
+
Visit "emoji-data.txt" with the rebuilt Emacs, and check that an
appropriate font is being used for the emoji (by default Emacs uses
"Noto Color Emoji"). Running the following command in that buffer
diff --git a/admin/notes/www b/admin/notes/www
index 61a80e3d196..d1a8f0637ff 100644
--- a/admin/notes/www
+++ b/admin/notes/www
@@ -26,7 +26,7 @@ more specialized, alternative to M-x vc-dir.
* Manual pages
The scripts admin/make-manuals, admin/upload-manuals can be used to do
-a complete update of the on-line manual pages (eg after a release).
+a complete update of the on-line manual pages (e.g. after a release).
* Renaming pages, redirects
@@ -99,7 +99,7 @@ https://lists.gnu.org/r/bug-gnulib/2012-12/msg00072.html
To use something other than CVS, convert the web-pages CVS repository
to the other VCS, then set up a two-way sync between them.
It needs to be two-way in case eg GNU webmasters make a change to the CVS.
-Ref eg
+Ref e.g.
https://github.com/mikjo/bigitr
https://lists.gnu.org/r/savannah-hackers-public/2013-04/msg00022.html
diff --git a/admin/unidata/BidiBrackets.txt b/admin/unidata/BidiBrackets.txt
index 89698f588ae..e138e7f5bea 100644
--- a/admin/unidata/BidiBrackets.txt
+++ b/admin/unidata/BidiBrackets.txt
@@ -1,6 +1,6 @@
-# BidiBrackets-14.0.0.txt
-# Date: 2021-06-30, 23:59:00 GMT [AG, LI, KW]
-# © 2021 Unicode®, Inc.
+# BidiBrackets-15.0.0.txt
+# Date: 2022-05-03, 18:42:00 GMT [AG, LI, KW]
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
# For terms of use, see https://www.unicode.org/terms_of_use.html
#
diff --git a/admin/unidata/BidiMirroring.txt b/admin/unidata/BidiMirroring.txt
index bd8e2c5d001..5861d6e7f4b 100644
--- a/admin/unidata/BidiMirroring.txt
+++ b/admin/unidata/BidiMirroring.txt
@@ -1,6 +1,6 @@
-# BidiMirroring-14.0.0.txt
-# Date: 2021-08-08, 22:55:00 GMT [KW, RP]
-# © 2021 Unicode®, Inc.
+# BidiMirroring-15.0.0.txt
+# Date: 2022-05-03, 18:47:00 GMT [KW, RP]
+# © 2022 Unicode®, Inc.
# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
@@ -15,7 +15,7 @@
# value, for which there is another Unicode character that typically has a glyph
# that is the mirror image of the original character's glyph.
#
-# The repertoire covered by the file is Unicode 14.0.0.
+# The repertoire covered by the file is Unicode 15.0.0.
#
# The file contains a list of lines with mappings from one code point
# to another one for character-based mirroring.
diff --git a/admin/unidata/Blocks.txt b/admin/unidata/Blocks.txt
index cc5d61988bb..12684594c9f 100644
--- a/admin/unidata/Blocks.txt
+++ b/admin/unidata/Blocks.txt
@@ -1,10 +1,10 @@
-# Blocks-14.0.0.txt
-# Date: 2021-01-22, 23:29:00 GMT [KW]
-# © 2021 Unicode®, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# Blocks-15.0.0.txt
+# Date: 2022-01-28, 20:58:00 GMT [KW]
+# © 2022 Unicode®, Inc.
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
+# For documentation, see https://www.unicode.org/reports/tr44/
#
# Format:
# Start Code..End Code; Block Name
@@ -15,7 +15,7 @@
# and underbars are ignored.
# For example, "Latin Extended-A" and "latin extended a" are equivalent.
# For more information on the comparison of property values,
-# see UAX #44: http://www.unicode.org/reports/tr44/
+# see UAX #44: https://www.unicode.org/reports/tr44/
#
# All block ranges start with a value where (cp MOD 16) = 0,
# and end with a value where (cp MOD 16) = 15. In other words,
@@ -241,6 +241,7 @@ FFF0..FFFF; Specials
10D00..10D3F; Hanifi Rohingya
10E60..10E7F; Rumi Numeral Symbols
10E80..10EBF; Yezidi
+10EC0..10EFF; Arabic Extended-C
10F00..10F2F; Old Sogdian
10F30..10F6F; Sogdian
10F70..10FAF; Old Uyghur
@@ -272,11 +273,13 @@ FFF0..FFFF; Specials
11A50..11AAF; Soyombo
11AB0..11ABF; Unified Canadian Aboriginal Syllabics Extended-A
11AC0..11AFF; Pau Cin Hau
+11B00..11B5F; Devanagari Extended-A
11C00..11C6F; Bhaiksuki
11C70..11CBF; Marchen
11D00..11D5F; Masaram Gondi
11D60..11DAF; Gunjala Gondi
11EE0..11EFF; Makasar
+11F00..11F5F; Kawi
11FB0..11FBF; Lisu Supplement
11FC0..11FFF; Tamil Supplement
12000..123FF; Cuneiform
@@ -284,7 +287,7 @@ FFF0..FFFF; Specials
12480..1254F; Early Dynastic Cuneiform
12F90..12FFF; Cypro-Minoan
13000..1342F; Egyptian Hieroglyphs
-13430..1343F; Egyptian Hieroglyph Format Controls
+13430..1345F; Egyptian Hieroglyph Format Controls
14400..1467F; Anatolian Hieroglyphs
16800..16A3F; Bamum Supplement
16A40..16A6F; Mro
@@ -309,6 +312,7 @@ FFF0..FFFF; Specials
1D000..1D0FF; Byzantine Musical Symbols
1D100..1D1FF; Musical Symbols
1D200..1D24F; Ancient Greek Musical Notation
+1D2C0..1D2DF; Kaktovik Numerals
1D2E0..1D2FF; Mayan Numerals
1D300..1D35F; Tai Xuan Jing Symbols
1D360..1D37F; Counting Rod Numerals
@@ -316,9 +320,11 @@ FFF0..FFFF; Specials
1D800..1DAAF; Sutton SignWriting
1DF00..1DFFF; Latin Extended-G
1E000..1E02F; Glagolitic Supplement
+1E030..1E08F; Cyrillic Extended-D
1E100..1E14F; Nyiakeng Puachue Hmong
1E290..1E2BF; Toto
1E2C0..1E2FF; Wancho
+1E4D0..1E4FF; Nag Mundari
1E7E0..1E7FF; Ethiopic Extended-B
1E800..1E8DF; Mende Kikakui
1E900..1E95F; Adlam
@@ -348,6 +354,7 @@ FFF0..FFFF; Specials
2CEB0..2EBEF; CJK Unified Ideographs Extension F
2F800..2FA1F; CJK Compatibility Ideographs Supplement
30000..3134F; CJK Unified Ideographs Extension G
+31350..323AF; CJK Unified Ideographs Extension H
E0000..E007F; Tags
E0100..E01EF; Variation Selectors Supplement
F0000..FFFFF; Supplementary Private Use Area-A
diff --git a/admin/unidata/IVD_Sequences.txt b/admin/unidata/IVD_Sequences.txt
index 886d8519ab5..86a4ab5138f 100644
--- a/admin/unidata/IVD_Sequences.txt
+++ b/admin/unidata/IVD_Sequences.txt
@@ -2,6 +2,9 @@
#
# History:
#
+# 2022-09-13 Registration of additional sequences in the Adobe-Japan1
+# collection.
+#
# 2020-11-06 Registration of additional sequences in the MSARG
# collection.
#
@@ -32,7 +35,7 @@
# For more details on the IVD, see UTS #37:
# https://www.unicode.org/reports/tr37/
#
-# Copyright 2006-2020 Unicode, Inc.
+# Copyright 2006-2022 Unicode, Inc.
# For terms of use, see: https://www.unicode.org/copyright.html#8
#
3402 E0100; Adobe-Japan1; CID+13698
@@ -39337,4 +39340,5 @@ FA29 E0100; Adobe-Japan1; CID+8687
2EB71 E0101; Moji_Joho; MJ059252
2EB79 E0100; Moji_Joho; MJ059255
2EB79 E0101; Moji_Joho; MJ059256
+31350 E0100; Adobe-Japan1; CID+19130
# EOF
diff --git a/admin/unidata/IdnaMappingTable.txt b/admin/unidata/IdnaMappingTable.txt
index 1b862827ef7..e4c06117929 100644
--- a/admin/unidata/IdnaMappingTable.txt
+++ b/admin/unidata/IdnaMappingTable.txt
@@ -1,13 +1,13 @@
# IdnaMappingTable.txt
-# Date: 2021-07-10, 00:49:51 GMT
-# © 2021 Unicode®, Inc.
+# Date: 2022-05-02, 19:29:26 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode IDNA Compatible Preprocessing for UTS #46
-# Version: 14.0.0
+# Version: 15.0.0
#
-# For documentation and usage, see http://www.unicode.org/reports/tr46
+# For documentation and usage, see https://www.unicode.org/reports/tr46
#
0000..002C ; disallowed_STD3_valid # 1.1 <control-0000>..COMMA
002D..002E ; valid # 1.1 HYPHEN-MINUS..FULL STOP
@@ -1278,7 +1278,8 @@
0CE6..0CEF ; valid # 1.1 KANNADA DIGIT ZERO..KANNADA DIGIT NINE
0CF0 ; disallowed # NA <reserved-0CF0>
0CF1..0CF2 ; valid # 5.0 KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
-0CF3..0CFF ; disallowed # NA <reserved-0CF3>..<reserved-0CFF>
+0CF3 ; valid # 15.0 KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT
+0CF4..0CFF ; disallowed # NA <reserved-0CF4>..<reserved-0CFF>
0D00 ; valid # 10.0 MALAYALAM SIGN COMBINING ANUSVARA ABOVE
0D01 ; valid # 7.0 MALAYALAM SIGN CANDRABINDU
0D02..0D03 ; valid # 1.1 MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
@@ -1386,7 +1387,8 @@
0EC6 ; valid # 1.1 LAO KO LA
0EC7 ; disallowed # NA <reserved-0EC7>
0EC8..0ECD ; valid # 1.1 LAO TONE MAI EK..LAO NIGGAHITA
-0ECE..0ECF ; disallowed # NA <reserved-0ECE>..<reserved-0ECF>
+0ECE ; valid # 15.0 LAO YAMAKKAN
+0ECF ; disallowed # NA <reserved-0ECF>
0ED0..0ED9 ; valid # 1.1 LAO DIGIT ZERO..LAO DIGIT NINE
0EDA..0EDB ; disallowed # NA <reserved-0EDA>..<reserved-0EDB>
0EDC ; mapped ; 0EAB 0E99 # 1.1 LAO HO NO
@@ -6206,7 +6208,8 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
10EAD ; valid ; ; NV8 # 13.0 YEZIDI HYPHENATION MARK
10EAE..10EAF ; disallowed # NA <reserved-10EAE>..<reserved-10EAF>
10EB0..10EB1 ; valid # 13.0 YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
-10EB2..10EFF ; disallowed # NA <reserved-10EB2>..<reserved-10EFF>
+10EB2..10EFC ; disallowed # NA <reserved-10EB2>..<reserved-10EFC>
+10EFD..10EFF ; valid # 15.0 ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA
10F00..10F1C ; valid # 11.0 OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
10F1D..10F26 ; valid ; ; NV8 # 11.0 OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF
10F27 ; valid # 11.0 OLD SOGDIAN LIGATURE AYIN-DALETH
@@ -6271,7 +6274,8 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
11213..11237 ; valid # 7.0 KHOJKI LETTER NYA..KHOJKI SIGN SHADDA
11238..1123D ; valid ; ; NV8 # 7.0 KHOJKI DANDA..KHOJKI ABBREVIATION SIGN
1123E ; valid # 9.0 KHOJKI SIGN SUKUN
-1123F..1127F ; disallowed # NA <reserved-1123F>..<reserved-1127F>
+1123F..11241 ; valid # 15.0 KHOJKI LETTER QA..KHOJKI VOWEL SIGN VOCALIC R
+11242..1127F ; disallowed # NA <reserved-11242>..<reserved-1127F>
11280..11286 ; valid # 8.0 MULTANI LETTER A..MULTANI LETTER GA
11287 ; disallowed # NA <reserved-11287>
11288 ; valid # 8.0 MULTANI LETTER GHA
@@ -6443,7 +6447,9 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
11AA3..11AAF ; disallowed # NA <reserved-11AA3>..<reserved-11AAF>
11AB0..11ABF ; valid # 14.0 CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA
11AC0..11AF8 ; valid # 7.0 PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL
-11AF9..11BFF ; disallowed # NA <reserved-11AF9>..<reserved-11BFF>
+11AF9..11AFF ; disallowed # NA <reserved-11AF9>..<reserved-11AFF>
+11B00..11B09 ; valid ; ; NV8 # 15.0 DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU
+11B0A..11BFF ; disallowed # NA <reserved-11B0A>..<reserved-11BFF>
11C00..11C08 ; valid # 9.0 BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L
11C09 ; disallowed # NA <reserved-11C09>
11C0A..11C36 ; valid # 9.0 BHAIKSUKI LETTER E..BHAIKSUKI VOWEL SIGN VOCALIC L
@@ -6489,7 +6495,15 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
11DAA..11EDF ; disallowed # NA <reserved-11DAA>..<reserved-11EDF>
11EE0..11EF6 ; valid # 11.0 MAKASAR LETTER KA..MAKASAR VOWEL SIGN O
11EF7..11EF8 ; valid ; ; NV8 # 11.0 MAKASAR PASSIMBANG..MAKASAR END OF SECTION
-11EF9..11FAF ; disallowed # NA <reserved-11EF9>..<reserved-11FAF>
+11EF9..11EFF ; disallowed # NA <reserved-11EF9>..<reserved-11EFF>
+11F00..11F10 ; valid # 15.0 KAWI SIGN CANDRABINDU..KAWI LETTER O
+11F11 ; disallowed # NA <reserved-11F11>
+11F12..11F3A ; valid # 15.0 KAWI LETTER KA..KAWI VOWEL SIGN VOCALIC R
+11F3B..11F3D ; disallowed # NA <reserved-11F3B>..<reserved-11F3D>
+11F3E..11F42 ; valid # 15.0 KAWI VOWEL SIGN E..KAWI CONJOINER
+11F43..11F4F ; valid ; ; NV8 # 15.0 KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL
+11F50..11F59 ; valid # 15.0 KAWI DIGIT ZERO..KAWI DIGIT NINE
+11F5A..11FAF ; disallowed # NA <reserved-11F5A>..<reserved-11FAF>
11FB0 ; valid # 13.0 LISU LETTER YHA
11FB1..11FBF ; disallowed # NA <reserved-11FB1>..<reserved-11FBF>
11FC0..11FF1 ; valid ; ; NV8 # 12.0 TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL SIGN VAKAIYARAA
@@ -6511,9 +6525,11 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
12FF1..12FF2 ; valid ; ; NV8 # 14.0 CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302
12FF3..12FFF ; disallowed # NA <reserved-12FF3>..<reserved-12FFF>
13000..1342E ; valid # 5.2 EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032
-1342F ; disallowed # NA <reserved-1342F>
+1342F ; valid # 15.0 EGYPTIAN HIEROGLYPH V011D
13430..13438 ; disallowed # 12.0 EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT
-13439..143FF ; disallowed # NA <reserved-13439>..<reserved-143FF>
+13439..1343F ; disallowed # 15.0 EGYPTIAN HIEROGLYPH INSERT AT MIDDLE..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE
+13440..13455 ; valid # 15.0 EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED
+13456..143FF ; disallowed # NA <reserved-13456>..<reserved-143FF>
14400..14646 ; valid # 8.0 ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530
14647..167FF ; disallowed # NA <reserved-14647>..<reserved-167FF>
16800..16A38 ; valid # 6.0 BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ
@@ -6615,9 +6631,13 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
1B000..1B001 ; valid # 6.0 KATAKANA LETTER ARCHAIC E..HIRAGANA LETTER ARCHAIC YE
1B002..1B11E ; valid # 10.0 HENTAIGANA LETTER A-1..HENTAIGANA LETTER N-MU-MO-2
1B11F..1B122 ; valid # 14.0 HIRAGANA LETTER ARCHAIC WU..KATAKANA LETTER ARCHAIC WU
-1B123..1B14F ; disallowed # NA <reserved-1B123>..<reserved-1B14F>
+1B123..1B131 ; disallowed # NA <reserved-1B123>..<reserved-1B131>
+1B132 ; valid # 15.0 HIRAGANA LETTER SMALL KO
+1B133..1B14F ; disallowed # NA <reserved-1B133>..<reserved-1B14F>
1B150..1B152 ; valid # 12.0 HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
-1B153..1B163 ; disallowed # NA <reserved-1B153>..<reserved-1B163>
+1B153..1B154 ; disallowed # NA <reserved-1B153>..<reserved-1B154>
+1B155 ; valid # 15.0 KATAKANA LETTER SMALL KO
+1B156..1B163 ; disallowed # NA <reserved-1B156>..<reserved-1B163>
1B164..1B167 ; valid # 12.0 KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
1B168..1B16F ; disallowed # NA <reserved-1B168>..<reserved-1B16F>
1B170..1B2FB ; valid # 10.0 NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB
@@ -6668,7 +6688,9 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
1D1E9..1D1EA ; valid ; ; NV8 # 14.0 MUSICAL SYMBOL SORI..MUSICAL SYMBOL KORON
1D1EB..1D1FF ; disallowed # NA <reserved-1D1EB>..<reserved-1D1FF>
1D200..1D245 ; valid ; ; NV8 # 4.1 GREEK VOCAL NOTATION SYMBOL-1..GREEK MUSICAL LEIMMA
-1D246..1D2DF ; disallowed # NA <reserved-1D246>..<reserved-1D2DF>
+1D246..1D2BF ; disallowed # NA <reserved-1D246>..<reserved-1D2BF>
+1D2C0..1D2D3 ; valid ; ; NV8 # 15.0 KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN
+1D2D4..1D2DF ; disallowed # NA <reserved-1D2D4>..<reserved-1D2DF>
1D2E0..1D2F3 ; valid ; ; NV8 # 11.0 MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN
1D2F4..1D2FF ; disallowed # NA <reserved-1D2F4>..<reserved-1D2FF>
1D300..1D356 ; valid ; ; NV8 # 4.0 MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
@@ -7701,7 +7723,9 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
1DAA1..1DAAF ; valid # 8.0 SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16
1DAB0..1DEFF ; disallowed # NA <reserved-1DAB0>..<reserved-1DEFF>
1DF00..1DF1E ; valid # 14.0 LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER S WITH CURL
-1DF1F..1DFFF ; disallowed # NA <reserved-1DF1F>..<reserved-1DFFF>
+1DF1F..1DF24 ; disallowed # NA <reserved-1DF1F>..<reserved-1DF24>
+1DF25..1DF2A ; valid # 15.0 LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK
+1DF2B..1DFFF ; disallowed # NA <reserved-1DF2B>..<reserved-1DFFF>
1E000..1E006 ; valid # 9.0 COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
1E007 ; disallowed # NA <reserved-1E007>
1E008..1E018 ; valid # 9.0 COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
@@ -7711,7 +7735,72 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
1E023..1E024 ; valid # 9.0 COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
1E025 ; disallowed # NA <reserved-1E025>
1E026..1E02A ; valid # 9.0 COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
-1E02B..1E0FF ; disallowed # NA <reserved-1E02B>..<reserved-1E0FF>
+1E02B..1E02F ; disallowed # NA <reserved-1E02B>..<reserved-1E02F>
+1E030 ; mapped ; 0430 # 15.0 MODIFIER LETTER CYRILLIC SMALL A
+1E031 ; mapped ; 0431 # 15.0 MODIFIER LETTER CYRILLIC SMALL BE
+1E032 ; mapped ; 0432 # 15.0 MODIFIER LETTER CYRILLIC SMALL VE
+1E033 ; mapped ; 0433 # 15.0 MODIFIER LETTER CYRILLIC SMALL GHE
+1E034 ; mapped ; 0434 # 15.0 MODIFIER LETTER CYRILLIC SMALL DE
+1E035 ; mapped ; 0435 # 15.0 MODIFIER LETTER CYRILLIC SMALL IE
+1E036 ; mapped ; 0436 # 15.0 MODIFIER LETTER CYRILLIC SMALL ZHE
+1E037 ; mapped ; 0437 # 15.0 MODIFIER LETTER CYRILLIC SMALL ZE
+1E038 ; mapped ; 0438 # 15.0 MODIFIER LETTER CYRILLIC SMALL I
+1E039 ; mapped ; 043A # 15.0 MODIFIER LETTER CYRILLIC SMALL KA
+1E03A ; mapped ; 043B # 15.0 MODIFIER LETTER CYRILLIC SMALL EL
+1E03B ; mapped ; 043C # 15.0 MODIFIER LETTER CYRILLIC SMALL EM
+1E03C ; mapped ; 043E # 15.0 MODIFIER LETTER CYRILLIC SMALL O
+1E03D ; mapped ; 043F # 15.0 MODIFIER LETTER CYRILLIC SMALL PE
+1E03E ; mapped ; 0440 # 15.0 MODIFIER LETTER CYRILLIC SMALL ER
+1E03F ; mapped ; 0441 # 15.0 MODIFIER LETTER CYRILLIC SMALL ES
+1E040 ; mapped ; 0442 # 15.0 MODIFIER LETTER CYRILLIC SMALL TE
+1E041 ; mapped ; 0443 # 15.0 MODIFIER LETTER CYRILLIC SMALL U
+1E042 ; mapped ; 0444 # 15.0 MODIFIER LETTER CYRILLIC SMALL EF
+1E043 ; mapped ; 0445 # 15.0 MODIFIER LETTER CYRILLIC SMALL HA
+1E044 ; mapped ; 0446 # 15.0 MODIFIER LETTER CYRILLIC SMALL TSE
+1E045 ; mapped ; 0447 # 15.0 MODIFIER LETTER CYRILLIC SMALL CHE
+1E046 ; mapped ; 0448 # 15.0 MODIFIER LETTER CYRILLIC SMALL SHA
+1E047 ; mapped ; 044B # 15.0 MODIFIER LETTER CYRILLIC SMALL YERU
+1E048 ; mapped ; 044D # 15.0 MODIFIER LETTER CYRILLIC SMALL E
+1E049 ; mapped ; 044E # 15.0 MODIFIER LETTER CYRILLIC SMALL YU
+1E04A ; mapped ; A689 # 15.0 MODIFIER LETTER CYRILLIC SMALL DZZE
+1E04B ; mapped ; 04D9 # 15.0 MODIFIER LETTER CYRILLIC SMALL SCHWA
+1E04C ; mapped ; 0456 # 15.0 MODIFIER LETTER CYRILLIC SMALL BYELORUSSIAN-UKRAINIAN I
+1E04D ; mapped ; 0458 # 15.0 MODIFIER LETTER CYRILLIC SMALL JE
+1E04E ; mapped ; 04E9 # 15.0 MODIFIER LETTER CYRILLIC SMALL BARRED O
+1E04F ; mapped ; 04AF # 15.0 MODIFIER LETTER CYRILLIC SMALL STRAIGHT U
+1E050 ; mapped ; 04CF # 15.0 MODIFIER LETTER CYRILLIC SMALL PALOCHKA
+1E051 ; mapped ; 0430 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER A
+1E052 ; mapped ; 0431 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER BE
+1E053 ; mapped ; 0432 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER VE
+1E054 ; mapped ; 0433 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER GHE
+1E055 ; mapped ; 0434 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER DE
+1E056 ; mapped ; 0435 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER IE
+1E057 ; mapped ; 0436 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER ZHE
+1E058 ; mapped ; 0437 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER ZE
+1E059 ; mapped ; 0438 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER I
+1E05A ; mapped ; 043A # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER KA
+1E05B ; mapped ; 043B # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER EL
+1E05C ; mapped ; 043E # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER O
+1E05D ; mapped ; 043F # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER PE
+1E05E ; mapped ; 0441 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER ES
+1E05F ; mapped ; 0443 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER U
+1E060 ; mapped ; 0444 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER EF
+1E061 ; mapped ; 0445 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER HA
+1E062 ; mapped ; 0446 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER TSE
+1E063 ; mapped ; 0447 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER CHE
+1E064 ; mapped ; 0448 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER SHA
+1E065 ; mapped ; 044A # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER HARD SIGN
+1E066 ; mapped ; 044B # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER YERU
+1E067 ; mapped ; 0491 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER GHE WITH UPTURN
+1E068 ; mapped ; 0456 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+1E069 ; mapped ; 0455 # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER DZE
+1E06A ; mapped ; 045F # 15.0 CYRILLIC SUBSCRIPT SMALL LETTER DZHE
+1E06B ; mapped ; 04AB # 15.0 MODIFIER LETTER CYRILLIC SMALL ES WITH DESCENDER
+1E06C ; mapped ; A651 # 15.0 MODIFIER LETTER CYRILLIC SMALL YERU WITH BACK YER
+1E06D ; mapped ; 04B1 # 15.0 MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE
+1E06E..1E08E ; disallowed # NA <reserved-1E06E>..<reserved-1E08E>
+1E08F ; valid # 15.0 COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+1E090..1E0FF ; disallowed # NA <reserved-1E090>..<reserved-1E0FF>
1E100..1E12C ; valid # 12.0 NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W
1E12D..1E12F ; disallowed # NA <reserved-1E12D>..<reserved-1E12F>
1E130..1E13D ; valid # 12.0 NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER
@@ -7726,7 +7815,9 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
1E2C0..1E2F9 ; valid # 12.0 WANCHO LETTER AA..WANCHO DIGIT NINE
1E2FA..1E2FE ; disallowed # NA <reserved-1E2FA>..<reserved-1E2FE>
1E2FF ; valid ; ; NV8 # 12.0 WANCHO NGUN SIGN
-1E300..1E7DF ; disallowed # NA <reserved-1E300>..<reserved-1E7DF>
+1E300..1E4CF ; disallowed # NA <reserved-1E300>..<reserved-1E4CF>
+1E4D0..1E4F9 ; valid # 15.0 NAG MUNDARI LETTER O..NAG MUNDARI DIGIT NINE
+1E4FA..1E7DF ; disallowed # NA <reserved-1E4FA>..<reserved-1E7DF>
1E7E0..1E7E6 ; valid # 14.0 ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO
1E7E7 ; disallowed # NA <reserved-1E7E7>
1E7E8..1E7EB ; valid # 14.0 ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE
@@ -8213,7 +8304,8 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
1F6D3..1F6D4 ; valid ; ; NV8 # 10.0 STUPA..PAGODA
1F6D5 ; valid ; ; NV8 # 12.0 HINDU TEMPLE
1F6D6..1F6D7 ; valid ; ; NV8 # 13.0 HUT..ELEVATOR
-1F6D8..1F6DC ; disallowed # NA <reserved-1F6D8>..<reserved-1F6DC>
+1F6D8..1F6DB ; disallowed # NA <reserved-1F6D8>..<reserved-1F6DB>
+1F6DC ; valid ; ; NV8 # 15.0 WIRELESS
1F6DD..1F6DF ; valid ; ; NV8 # 14.0 PLAYGROUND SLIDE..RING BUOY
1F6E0..1F6EC ; valid ; ; NV8 # 7.0 HAMMER AND WRENCH..AIRPLANE ARRIVING
1F6ED..1F6EF ; disallowed # NA <reserved-1F6ED>..<reserved-1F6EF>
@@ -8225,10 +8317,13 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
1F6FB..1F6FC ; valid ; ; NV8 # 13.0 PICKUP TRUCK..ROLLER SKATE
1F6FD..1F6FF ; disallowed # NA <reserved-1F6FD>..<reserved-1F6FF>
1F700..1F773 ; valid ; ; NV8 # 6.0 ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE
-1F774..1F77F ; disallowed # NA <reserved-1F774>..<reserved-1F77F>
+1F774..1F776 ; valid ; ; NV8 # 15.0 LOT OF FORTUNE..LUNAR ECLIPSE
+1F777..1F77A ; disallowed # NA <reserved-1F777>..<reserved-1F77A>
+1F77B..1F77F ; valid ; ; NV8 # 15.0 HAUMEA..ORCUS
1F780..1F7D4 ; valid ; ; NV8 # 7.0 BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..HEAVY TWELVE POINTED PINWHEEL STAR
1F7D5..1F7D8 ; valid ; ; NV8 # 11.0 CIRCLED TRIANGLE..NEGATIVE CIRCLED SQUARE
-1F7D9..1F7DF ; disallowed # NA <reserved-1F7D9>..<reserved-1F7DF>
+1F7D9 ; valid ; ; NV8 # 15.0 NINE POINTED WHITE STAR
+1F7DA..1F7DF ; disallowed # NA <reserved-1F7DA>..<reserved-1F7DF>
1F7E0..1F7EB ; valid ; ; NV8 # 12.0 LARGE ORANGE CIRCLE..LARGE BROWN SQUARE
1F7EC..1F7EF ; disallowed # NA <reserved-1F7EC>..<reserved-1F7EF>
1F7F0 ; valid ; ; NV8 # 14.0 HEAVY EQUALS SIGN
@@ -8295,30 +8390,37 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
1FA6E..1FA6F ; disallowed # NA <reserved-1FA6E>..<reserved-1FA6F>
1FA70..1FA73 ; valid ; ; NV8 # 12.0 BALLET SHOES..SHORTS
1FA74 ; valid ; ; NV8 # 13.0 THONG SANDAL
-1FA75..1FA77 ; disallowed # NA <reserved-1FA75>..<reserved-1FA77>
+1FA75..1FA77 ; valid ; ; NV8 # 15.0 LIGHT BLUE HEART..PINK HEART
1FA78..1FA7A ; valid ; ; NV8 # 12.0 DROP OF BLOOD..STETHOSCOPE
1FA7B..1FA7C ; valid ; ; NV8 # 14.0 X-RAY..CRUTCH
1FA7D..1FA7F ; disallowed # NA <reserved-1FA7D>..<reserved-1FA7F>
1FA80..1FA82 ; valid ; ; NV8 # 12.0 YO-YO..PARACHUTE
1FA83..1FA86 ; valid ; ; NV8 # 13.0 BOOMERANG..NESTING DOLLS
-1FA87..1FA8F ; disallowed # NA <reserved-1FA87>..<reserved-1FA8F>
+1FA87..1FA88 ; valid ; ; NV8 # 15.0 MARACAS..FLUTE
+1FA89..1FA8F ; disallowed # NA <reserved-1FA89>..<reserved-1FA8F>
1FA90..1FA95 ; valid ; ; NV8 # 12.0 RINGED PLANET..BANJO
1FA96..1FAA8 ; valid ; ; NV8 # 13.0 MILITARY HELMET..ROCK
1FAA9..1FAAC ; valid ; ; NV8 # 14.0 MIRROR BALL..HAMSA
-1FAAD..1FAAF ; disallowed # NA <reserved-1FAAD>..<reserved-1FAAF>
+1FAAD..1FAAF ; valid ; ; NV8 # 15.0 FOLDING HAND FAN..KHANDA
1FAB0..1FAB6 ; valid ; ; NV8 # 13.0 FLY..FEATHER
1FAB7..1FABA ; valid ; ; NV8 # 14.0 LOTUS..NEST WITH EGGS
-1FABB..1FABF ; disallowed # NA <reserved-1FABB>..<reserved-1FABF>
+1FABB..1FABD ; valid ; ; NV8 # 15.0 HYACINTH..WING
+1FABE ; disallowed # NA <reserved-1FABE>
+1FABF ; valid ; ; NV8 # 15.0 GOOSE
1FAC0..1FAC2 ; valid ; ; NV8 # 13.0 ANATOMICAL HEART..PEOPLE HUGGING
1FAC3..1FAC5 ; valid ; ; NV8 # 14.0 PREGNANT MAN..PERSON WITH CROWN
-1FAC6..1FACF ; disallowed # NA <reserved-1FAC6>..<reserved-1FACF>
+1FAC6..1FACD ; disallowed # NA <reserved-1FAC6>..<reserved-1FACD>
+1FACE..1FACF ; valid ; ; NV8 # 15.0 MOOSE..DONKEY
1FAD0..1FAD6 ; valid ; ; NV8 # 13.0 BLUEBERRIES..TEAPOT
1FAD7..1FAD9 ; valid ; ; NV8 # 14.0 POURING LIQUID..JAR
-1FADA..1FADF ; disallowed # NA <reserved-1FADA>..<reserved-1FADF>
+1FADA..1FADB ; valid ; ; NV8 # 15.0 GINGER ROOT..PEA POD
+1FADC..1FADF ; disallowed # NA <reserved-1FADC>..<reserved-1FADF>
1FAE0..1FAE7 ; valid ; ; NV8 # 14.0 MELTING FACE..BUBBLES
-1FAE8..1FAEF ; disallowed # NA <reserved-1FAE8>..<reserved-1FAEF>
+1FAE8 ; valid ; ; NV8 # 15.0 SHAKING FACE
+1FAE9..1FAEF ; disallowed # NA <reserved-1FAE9>..<reserved-1FAEF>
1FAF0..1FAF6 ; valid ; ; NV8 # 14.0 HAND WITH INDEX FINGER AND THUMB CROSSED..HEART HANDS
-1FAF7..1FAFF ; disallowed # NA <reserved-1FAF7>..<reserved-1FAFF>
+1FAF7..1FAF8 ; valid ; ; NV8 # 15.0 LEFTWARDS PUSHING HAND..RIGHTWARDS PUSHING HAND
+1FAF9..1FAFF ; disallowed # NA <reserved-1FAF9>..<reserved-1FAFF>
1FB00..1FB92 ; valid ; ; NV8 # 13.0 BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK
1FB93 ; disallowed # NA <reserved-1FB93>
1FB94..1FBCA ; valid ; ; NV8 # 13.0 LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON
@@ -8341,7 +8443,8 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
2A6E0..2A6FF ; disallowed # NA <reserved-2A6E0>..<reserved-2A6FF>
2A700..2B734 ; valid # 5.2 CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B734
2B735..2B738 ; valid # 14.0 CJK UNIFIED IDEOGRAPH-2B735..CJK UNIFIED IDEOGRAPH-2B738
-2B739..2B73F ; disallowed # NA <reserved-2B739>..<reserved-2B73F>
+2B739 ; valid # 15.0 CJK UNIFIED IDEOGRAPH-2B739
+2B73A..2B73F ; disallowed # NA <reserved-2B73A>..<reserved-2B73F>
2B740..2B81D ; valid # 6.0 CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
2B81E..2B81F ; disallowed # NA <reserved-2B81E>..<reserved-2B81F>
2B820..2CEA1 ; valid # 8.0 CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
@@ -8883,7 +8986,9 @@ FFFE..FFFF ; disallowed # 1.1 <noncharacter-FFFE
2FA1E..2FFFD ; disallowed # NA <reserved-2FA1E>..<reserved-2FFFD>
2FFFE..2FFFF ; disallowed # 2.0 <noncharacter-2FFFE>..<noncharacter-2FFFF>
30000..3134A ; valid # 13.0 CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
-3134B..3FFFD ; disallowed # NA <reserved-3134B>..<reserved-3FFFD>
+3134B..3134F ; disallowed # NA <reserved-3134B>..<reserved-3134F>
+31350..323AF ; valid # 15.0 CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF
+323B0..3FFFD ; disallowed # NA <reserved-323B0>..<reserved-3FFFD>
3FFFE..3FFFF ; disallowed # 2.0 <noncharacter-3FFFE>..<noncharacter-3FFFF>
40000..4FFFD ; disallowed # NA <reserved-40000>..<reserved-4FFFD>
4FFFE..4FFFF ; disallowed # 2.0 <noncharacter-4FFFE>..<noncharacter-4FFFF>
diff --git a/admin/unidata/Makefile.in b/admin/unidata/Makefile.in
index 4b3e72f0131..f3e653879c0 100644
--- a/admin/unidata/Makefile.in
+++ b/admin/unidata/Makefile.in
@@ -138,7 +138,8 @@ gen-clean:
rm -f ${unidir}/charscript.el*
rm -f ${unidir}/emoji-zwj.el*
rm -f ${unifiles} ${unidir}/charprop.el
- rm -f ${unidir}/emoji-labels.el*
+ rm -f ${unidir}/emoji-labels.el ${unidir}/idna-mapping.el \
+ ${unidir}/uni-confusable.el ${unidir}/uni-scripts.el
## ref: https://lists.gnu.org/r/emacs-devel/2013-11/msg01029.html
maintainer-clean: gen-clean distclean
diff --git a/admin/unidata/NormalizationTest.txt b/admin/unidata/NormalizationTest.txt
index 302c35f37c7..e75b4801c9b 100644
--- a/admin/unidata/NormalizationTest.txt
+++ b/admin/unidata/NormalizationTest.txt
@@ -1,11 +1,11 @@
-# NormalizationTest-14.0.0.txt
-# Date: 2021-05-28, 21:49:12 GMT
-# © 2021 Unicode®, Inc.
+# NormalizationTest-15.0.0.txt
+# Date: 2022-04-02, 01:29:09 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
+# For documentation, see https://www.unicode.org/reports/tr44/
#
# Normalization Test Suite
# Format:
@@ -16208,6 +16208,68 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
1D7FD;1D7FD;1D7FD;0037;0037; # (𝟽; 𝟽; 𝟽; 7; 7; ) MATHEMATICAL MONOSPACE DIGIT SEVEN
1D7FE;1D7FE;1D7FE;0038;0038; # (𝟾; 𝟾; 𝟾; 8; 8; ) MATHEMATICAL MONOSPACE DIGIT EIGHT
1D7FF;1D7FF;1D7FF;0039;0039; # (𝟿; 𝟿; 𝟿; 9; 9; ) MATHEMATICAL MONOSPACE DIGIT NINE
+1E030;1E030;1E030;0430;0430; # (𞀰; 𞀰; 𞀰; а; а; ) MODIFIER LETTER CYRILLIC SMALL A
+1E031;1E031;1E031;0431;0431; # (𞀱; 𞀱; 𞀱; б; б; ) MODIFIER LETTER CYRILLIC SMALL BE
+1E032;1E032;1E032;0432;0432; # (𞀲; 𞀲; 𞀲; в; в; ) MODIFIER LETTER CYRILLIC SMALL VE
+1E033;1E033;1E033;0433;0433; # (𞀳; 𞀳; 𞀳; г; г; ) MODIFIER LETTER CYRILLIC SMALL GHE
+1E034;1E034;1E034;0434;0434; # (𞀴; 𞀴; 𞀴; д; д; ) MODIFIER LETTER CYRILLIC SMALL DE
+1E035;1E035;1E035;0435;0435; # (𞀵; 𞀵; 𞀵; е; е; ) MODIFIER LETTER CYRILLIC SMALL IE
+1E036;1E036;1E036;0436;0436; # (𞀶; 𞀶; 𞀶; ж; ж; ) MODIFIER LETTER CYRILLIC SMALL ZHE
+1E037;1E037;1E037;0437;0437; # (𞀷; 𞀷; 𞀷; з; з; ) MODIFIER LETTER CYRILLIC SMALL ZE
+1E038;1E038;1E038;0438;0438; # (𞀸; 𞀸; 𞀸; и; и; ) MODIFIER LETTER CYRILLIC SMALL I
+1E039;1E039;1E039;043A;043A; # (𞀹; 𞀹; 𞀹; к; к; ) MODIFIER LETTER CYRILLIC SMALL KA
+1E03A;1E03A;1E03A;043B;043B; # (𞀺; 𞀺; 𞀺; л; л; ) MODIFIER LETTER CYRILLIC SMALL EL
+1E03B;1E03B;1E03B;043C;043C; # (𞀻; 𞀻; 𞀻; м; м; ) MODIFIER LETTER CYRILLIC SMALL EM
+1E03C;1E03C;1E03C;043E;043E; # (𞀼; 𞀼; 𞀼; о; о; ) MODIFIER LETTER CYRILLIC SMALL O
+1E03D;1E03D;1E03D;043F;043F; # (𞀽; 𞀽; 𞀽; п; п; ) MODIFIER LETTER CYRILLIC SMALL PE
+1E03E;1E03E;1E03E;0440;0440; # (𞀾; 𞀾; 𞀾; р; р; ) MODIFIER LETTER CYRILLIC SMALL ER
+1E03F;1E03F;1E03F;0441;0441; # (𞀿; 𞀿; 𞀿; с; с; ) MODIFIER LETTER CYRILLIC SMALL ES
+1E040;1E040;1E040;0442;0442; # (𞁀; 𞁀; 𞁀; т; т; ) MODIFIER LETTER CYRILLIC SMALL TE
+1E041;1E041;1E041;0443;0443; # (𞁁; 𞁁; 𞁁; у; у; ) MODIFIER LETTER CYRILLIC SMALL U
+1E042;1E042;1E042;0444;0444; # (𞁂; 𞁂; 𞁂; ф; ф; ) MODIFIER LETTER CYRILLIC SMALL EF
+1E043;1E043;1E043;0445;0445; # (𞁃; 𞁃; 𞁃; х; х; ) MODIFIER LETTER CYRILLIC SMALL HA
+1E044;1E044;1E044;0446;0446; # (𞁄; 𞁄; 𞁄; ц; ц; ) MODIFIER LETTER CYRILLIC SMALL TSE
+1E045;1E045;1E045;0447;0447; # (𞁅; 𞁅; 𞁅; ч; ч; ) MODIFIER LETTER CYRILLIC SMALL CHE
+1E046;1E046;1E046;0448;0448; # (𞁆; 𞁆; 𞁆; ш; ш; ) MODIFIER LETTER CYRILLIC SMALL SHA
+1E047;1E047;1E047;044B;044B; # (𞁇; 𞁇; 𞁇; ы; ы; ) MODIFIER LETTER CYRILLIC SMALL YERU
+1E048;1E048;1E048;044D;044D; # (𞁈; 𞁈; 𞁈; э; э; ) MODIFIER LETTER CYRILLIC SMALL E
+1E049;1E049;1E049;044E;044E; # (𞁉; 𞁉; 𞁉; ю; ю; ) MODIFIER LETTER CYRILLIC SMALL YU
+1E04A;1E04A;1E04A;A689;A689; # (𞁊; 𞁊; 𞁊; ꚉ; ꚉ; ) MODIFIER LETTER CYRILLIC SMALL DZZE
+1E04B;1E04B;1E04B;04D9;04D9; # (𞁋; 𞁋; 𞁋; ә; ә; ) MODIFIER LETTER CYRILLIC SMALL SCHWA
+1E04C;1E04C;1E04C;0456;0456; # (𞁌; 𞁌; 𞁌; і; і; ) MODIFIER LETTER CYRILLIC SMALL BYELORUSSIAN-UKRAINIAN I
+1E04D;1E04D;1E04D;0458;0458; # (𞁍; 𞁍; 𞁍; ј; ј; ) MODIFIER LETTER CYRILLIC SMALL JE
+1E04E;1E04E;1E04E;04E9;04E9; # (𞁎; 𞁎; 𞁎; ө; ө; ) MODIFIER LETTER CYRILLIC SMALL BARRED O
+1E04F;1E04F;1E04F;04AF;04AF; # (𞁏; 𞁏; 𞁏; ү; ү; ) MODIFIER LETTER CYRILLIC SMALL STRAIGHT U
+1E050;1E050;1E050;04CF;04CF; # (𞁐; 𞁐; 𞁐; ӏ; ӏ; ) MODIFIER LETTER CYRILLIC SMALL PALOCHKA
+1E051;1E051;1E051;0430;0430; # (𞁑; 𞁑; 𞁑; а; а; ) CYRILLIC SUBSCRIPT SMALL LETTER A
+1E052;1E052;1E052;0431;0431; # (𞁒; 𞁒; 𞁒; б; б; ) CYRILLIC SUBSCRIPT SMALL LETTER BE
+1E053;1E053;1E053;0432;0432; # (𞁓; 𞁓; 𞁓; в; в; ) CYRILLIC SUBSCRIPT SMALL LETTER VE
+1E054;1E054;1E054;0433;0433; # (𞁔; 𞁔; 𞁔; г; г; ) CYRILLIC SUBSCRIPT SMALL LETTER GHE
+1E055;1E055;1E055;0434;0434; # (𞁕; 𞁕; 𞁕; д; д; ) CYRILLIC SUBSCRIPT SMALL LETTER DE
+1E056;1E056;1E056;0435;0435; # (𞁖; 𞁖; 𞁖; е; е; ) CYRILLIC SUBSCRIPT SMALL LETTER IE
+1E057;1E057;1E057;0436;0436; # (𞁗; 𞁗; 𞁗; ж; ж; ) CYRILLIC SUBSCRIPT SMALL LETTER ZHE
+1E058;1E058;1E058;0437;0437; # (𞁘; 𞁘; 𞁘; з; з; ) CYRILLIC SUBSCRIPT SMALL LETTER ZE
+1E059;1E059;1E059;0438;0438; # (𞁙; 𞁙; 𞁙; и; и; ) CYRILLIC SUBSCRIPT SMALL LETTER I
+1E05A;1E05A;1E05A;043A;043A; # (𞁚; 𞁚; 𞁚; к; к; ) CYRILLIC SUBSCRIPT SMALL LETTER KA
+1E05B;1E05B;1E05B;043B;043B; # (𞁛; 𞁛; 𞁛; л; л; ) CYRILLIC SUBSCRIPT SMALL LETTER EL
+1E05C;1E05C;1E05C;043E;043E; # (𞁜; 𞁜; 𞁜; о; о; ) CYRILLIC SUBSCRIPT SMALL LETTER O
+1E05D;1E05D;1E05D;043F;043F; # (𞁝; 𞁝; 𞁝; п; п; ) CYRILLIC SUBSCRIPT SMALL LETTER PE
+1E05E;1E05E;1E05E;0441;0441; # (𞁞; 𞁞; 𞁞; с; с; ) CYRILLIC SUBSCRIPT SMALL LETTER ES
+1E05F;1E05F;1E05F;0443;0443; # (𞁟; 𞁟; 𞁟; у; у; ) CYRILLIC SUBSCRIPT SMALL LETTER U
+1E060;1E060;1E060;0444;0444; # (𞁠; 𞁠; 𞁠; ф; ф; ) CYRILLIC SUBSCRIPT SMALL LETTER EF
+1E061;1E061;1E061;0445;0445; # (𞁡; 𞁡; 𞁡; х; х; ) CYRILLIC SUBSCRIPT SMALL LETTER HA
+1E062;1E062;1E062;0446;0446; # (𞁢; 𞁢; 𞁢; ц; ц; ) CYRILLIC SUBSCRIPT SMALL LETTER TSE
+1E063;1E063;1E063;0447;0447; # (𞁣; 𞁣; 𞁣; ч; ч; ) CYRILLIC SUBSCRIPT SMALL LETTER CHE
+1E064;1E064;1E064;0448;0448; # (𞁤; 𞁤; 𞁤; ш; ш; ) CYRILLIC SUBSCRIPT SMALL LETTER SHA
+1E065;1E065;1E065;044A;044A; # (𞁥; 𞁥; 𞁥; ъ; ъ; ) CYRILLIC SUBSCRIPT SMALL LETTER HARD SIGN
+1E066;1E066;1E066;044B;044B; # (𞁦; 𞁦; 𞁦; ы; ы; ) CYRILLIC SUBSCRIPT SMALL LETTER YERU
+1E067;1E067;1E067;0491;0491; # (𞁧; 𞁧; 𞁧; ґ; ґ; ) CYRILLIC SUBSCRIPT SMALL LETTER GHE WITH UPTURN
+1E068;1E068;1E068;0456;0456; # (𞁨; 𞁨; 𞁨; і; і; ) CYRILLIC SUBSCRIPT SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+1E069;1E069;1E069;0455;0455; # (𞁩; 𞁩; 𞁩; ѕ; ѕ; ) CYRILLIC SUBSCRIPT SMALL LETTER DZE
+1E06A;1E06A;1E06A;045F;045F; # (𞁪; 𞁪; 𞁪; џ; џ; ) CYRILLIC SUBSCRIPT SMALL LETTER DZHE
+1E06B;1E06B;1E06B;04AB;04AB; # (𞁫; 𞁫; 𞁫; ҫ; ҫ; ) MODIFIER LETTER CYRILLIC SMALL ES WITH DESCENDER
+1E06C;1E06C;1E06C;A651;A651; # (𞁬; 𞁬; 𞁬; ꙑ; ꙑ; ) MODIFIER LETTER CYRILLIC SMALL YERU WITH BACK YER
+1E06D;1E06D;1E06D;04B1;04B1; # (𞁭; 𞁭; 𞁭; ұ; ұ; ) MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE
1EE00;1EE00;1EE00;0627;0627; # (𞸀; 𞸀; 𞸀; ا; ا; ) ARABIC MATHEMATICAL ALEF
1EE01;1EE01;1EE01;0628;0628; # (𞸁; 𞸁; 𞸁; ب; ب; ) ARABIC MATHEMATICAL BEH
1EE02;1EE02;1EE02;062C;062C; # (𞸂; 𞸂; 𞸂; ج; ج; ) ARABIC MATHEMATICAL JEEM
@@ -18496,6 +18558,12 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 10EAB 0315 0300 05AE 0062;0061 05AE 10EAB 0300 0315 0062;0061 05AE 10EAB 0300 0315 0062;0061 05AE 10EAB 0300 0315 0062;0061 05AE 10EAB 0300 0315 0062; # (a◌𐺫◌̕◌̀◌֮b; a◌֮◌𐺫◌̀◌̕b; a◌֮◌𐺫◌̀◌̕b; a◌֮◌𐺫◌̀◌̕b; a◌֮◌𐺫◌̀◌̕b; ) LATIN SMALL LETTER A, YEZIDI COMBINING HAMZA MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 10EAC 0062;00E0 05AE 10EAC 0315 0062;0061 05AE 0300 10EAC 0315 0062;00E0 05AE 10EAC 0315 0062;0061 05AE 0300 10EAC 0315 0062; # (a◌̕◌̀◌֮◌𐺬b; à◌֮◌𐺬◌̕b; a◌֮◌̀◌𐺬◌̕b; à◌֮◌𐺬◌̕b; a◌֮◌̀◌𐺬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, YEZIDI COMBINING MADDA MARK, LATIN SMALL LETTER B
0061 10EAC 0315 0300 05AE 0062;0061 05AE 10EAC 0300 0315 0062;0061 05AE 10EAC 0300 0315 0062;0061 05AE 10EAC 0300 0315 0062;0061 05AE 10EAC 0300 0315 0062; # (a◌𐺬◌̕◌̀◌֮b; a◌֮◌𐺬◌̀◌̕b; a◌֮◌𐺬◌̀◌̕b; a◌֮◌𐺬◌̀◌̕b; a◌֮◌𐺬◌̀◌̕b; ) LATIN SMALL LETTER A, YEZIDI COMBINING MADDA MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10EFD 0062;0061 1DFA 0316 10EFD 059A 0062;0061 1DFA 0316 10EFD 059A 0062;0061 1DFA 0316 10EFD 059A 0062;0061 1DFA 0316 10EFD 059A 0062; # (a◌֚◌̖◌᷺◌𐻽b; a◌᷺◌̖◌𐻽◌֚b; a◌᷺◌̖◌𐻽◌֚b; a◌᷺◌̖◌𐻽◌֚b; a◌᷺◌̖◌𐻽◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, ARABIC SMALL LOW WORD SAKTA, LATIN SMALL LETTER B
+0061 10EFD 059A 0316 1DFA 0062;0061 1DFA 10EFD 0316 059A 0062;0061 1DFA 10EFD 0316 059A 0062;0061 1DFA 10EFD 0316 059A 0062;0061 1DFA 10EFD 0316 059A 0062; # (a◌𐻽◌֚◌̖◌᷺b; a◌᷺◌𐻽◌̖◌֚b; a◌᷺◌𐻽◌̖◌֚b; a◌᷺◌𐻽◌̖◌֚b; a◌᷺◌𐻽◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW WORD SAKTA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10EFE 0062;0061 1DFA 0316 10EFE 059A 0062;0061 1DFA 0316 10EFE 059A 0062;0061 1DFA 0316 10EFE 059A 0062;0061 1DFA 0316 10EFE 059A 0062; # (a◌֚◌̖◌᷺◌𐻾b; a◌᷺◌̖◌𐻾◌֚b; a◌᷺◌̖◌𐻾◌֚b; a◌᷺◌̖◌𐻾◌֚b; a◌᷺◌̖◌𐻾◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, ARABIC SMALL LOW WORD QASR, LATIN SMALL LETTER B
+0061 10EFE 059A 0316 1DFA 0062;0061 1DFA 10EFE 0316 059A 0062;0061 1DFA 10EFE 0316 059A 0062;0061 1DFA 10EFE 0316 059A 0062;0061 1DFA 10EFE 0316 059A 0062; # (a◌𐻾◌֚◌̖◌᷺b; a◌᷺◌𐻾◌̖◌֚b; a◌᷺◌𐻾◌̖◌֚b; a◌᷺◌𐻾◌̖◌֚b; a◌᷺◌𐻾◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW WORD QASR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 10EFF 0062;0061 1DFA 0316 10EFF 059A 0062;0061 1DFA 0316 10EFF 059A 0062;0061 1DFA 0316 10EFF 059A 0062;0061 1DFA 0316 10EFF 059A 0062; # (a◌֚◌̖◌᷺◌𐻿b; a◌᷺◌̖◌𐻿◌֚b; a◌᷺◌̖◌𐻿◌֚b; a◌᷺◌̖◌𐻿◌֚b; a◌᷺◌̖◌𐻿◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, ARABIC SMALL LOW WORD MADDA, LATIN SMALL LETTER B
+0061 10EFF 059A 0316 1DFA 0062;0061 1DFA 10EFF 0316 059A 0062;0061 1DFA 10EFF 0316 059A 0062;0061 1DFA 10EFF 0316 059A 0062;0061 1DFA 10EFF 0316 059A 0062; # (a◌𐻿◌֚◌̖◌᷺b; a◌᷺◌𐻿◌̖◌֚b; a◌᷺◌𐻿◌̖◌֚b; a◌᷺◌𐻿◌̖◌֚b; a◌᷺◌𐻿◌̖◌֚b; ) LATIN SMALL LETTER A, ARABIC SMALL LOW WORD MADDA, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 059A 0316 1DFA 10F46 0062;0061 1DFA 0316 10F46 059A 0062;0061 1DFA 0316 10F46 059A 0062;0061 1DFA 0316 10F46 059A 0062;0061 1DFA 0316 10F46 059A 0062; # (a◌֚◌̖◌᷺◌𐽆b; a◌᷺◌̖◌𐽆◌֚b; a◌᷺◌̖◌𐽆◌֚b; a◌᷺◌̖◌𐽆◌֚b; a◌᷺◌̖◌𐽆◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, SOGDIAN COMBINING DOT BELOW, LATIN SMALL LETTER B
0061 10F46 059A 0316 1DFA 0062;0061 1DFA 10F46 0316 059A 0062;0061 1DFA 10F46 0316 059A 0062;0061 1DFA 10F46 0316 059A 0062;0061 1DFA 10F46 0316 059A 0062; # (a◌𐽆◌֚◌̖◌᷺b; a◌᷺◌𐽆◌̖◌֚b; a◌᷺◌𐽆◌̖◌֚b; a◌᷺◌𐽆◌̖◌֚b; a◌᷺◌𐽆◌̖◌֚b; ) LATIN SMALL LETTER A, SOGDIAN COMBINING DOT BELOW, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 059A 0316 1DFA 10F47 0062;0061 1DFA 0316 10F47 059A 0062;0061 1DFA 0316 10F47 059A 0062;0061 1DFA 0316 10F47 059A 0062;0061 1DFA 0316 10F47 059A 0062; # (a◌֚◌̖◌᷺◌𐽇b; a◌᷺◌̖◌𐽇◌֚b; a◌᷺◌̖◌𐽇◌֚b; a◌᷺◌̖◌𐽇◌֚b; a◌᷺◌̖◌𐽇◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, SOGDIAN COMBINING TWO DOTS BELOW, LATIN SMALL LETTER B
@@ -18640,6 +18708,10 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 11D45 05B0 094D 3099 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062;0061 3099 11D45 094D 05B0 0062; # (a◌𑵅◌ְ◌्◌゙b; a◌゙◌𑵅◌्◌ְb; a◌゙◌𑵅◌्◌ְb; a◌゙◌𑵅◌्◌ְb; a◌゙◌𑵅◌्◌ְb; ) LATIN SMALL LETTER A, MASARAM GONDI VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 05B0 094D 3099 11D97 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062;0061 3099 094D 11D97 05B0 0062; # (a◌ְ◌्◌゙◌𑶗b; a◌゙◌्◌𑶗◌ְb; a◌゙◌्◌𑶗◌ְb; a◌゙◌्◌𑶗◌ְb; a◌゙◌्◌𑶗◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, GUNJALA GONDI VIRAMA, LATIN SMALL LETTER B
0061 11D97 05B0 094D 3099 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062;0061 3099 11D97 094D 05B0 0062; # (a◌𑶗◌ְ◌्◌゙b; a◌゙◌𑶗◌्◌ְb; a◌゙◌𑶗◌्◌ְb; a◌゙◌𑶗◌्◌ְb; a◌゙◌𑶗◌्◌ְb; ) LATIN SMALL LETTER A, GUNJALA GONDI VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11F41 0062;0061 3099 094D 11F41 05B0 0062;0061 3099 094D 11F41 05B0 0062;0061 3099 094D 11F41 05B0 0062;0061 3099 094D 11F41 05B0 0062; # (a◌ְ◌्◌゙𑽁b; a◌゙◌्𑽁◌ְb; a◌゙◌्𑽁◌ְb; a◌゙◌्𑽁◌ְb; a◌゙◌्𑽁◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KAWI SIGN KILLER, LATIN SMALL LETTER B
+0061 11F41 05B0 094D 3099 0062;0061 3099 11F41 094D 05B0 0062;0061 3099 11F41 094D 05B0 0062;0061 3099 11F41 094D 05B0 0062;0061 3099 11F41 094D 05B0 0062; # (a𑽁◌ְ◌्◌゙b; a◌゙𑽁◌्◌ְb; a◌゙𑽁◌्◌ְb; a◌゙𑽁◌्◌ְb; a◌゙𑽁◌्◌ְb; ) LATIN SMALL LETTER A, KAWI SIGN KILLER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
+0061 05B0 094D 3099 11F42 0062;0061 3099 094D 11F42 05B0 0062;0061 3099 094D 11F42 05B0 0062;0061 3099 094D 11F42 05B0 0062;0061 3099 094D 11F42 05B0 0062; # (a◌ְ◌्◌゙◌𑽂b; a◌゙◌्◌𑽂◌ְb; a◌゙◌्◌𑽂◌ְb; a◌゙◌्◌𑽂◌ְb; a◌゙◌्◌𑽂◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KAWI CONJOINER, LATIN SMALL LETTER B
+0061 11F42 05B0 094D 3099 0062;0061 3099 11F42 094D 05B0 0062;0061 3099 11F42 094D 05B0 0062;0061 3099 11F42 094D 05B0 0062;0061 3099 11F42 094D 05B0 0062; # (a◌𑽂◌ְ◌्◌゙b; a◌゙◌𑽂◌्◌ְb; a◌゙◌𑽂◌्◌ְb; a◌゙◌𑽂◌्◌ְb; a◌゙◌𑽂◌्◌ְb; ) LATIN SMALL LETTER A, KAWI CONJOINER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B
0061 16FF0 0334 16AF0 0062;0061 0334 16AF0 16FF0 0062;0061 0334 16AF0 16FF0 0062;0061 0334 16AF0 16FF0 0062;0061 0334 16AF0 16FF0 0062; # (a𖿰◌̴◌𖫰b; a◌̴◌𖫰𖿰b; a◌̴◌𖫰𖿰b; a◌̴◌𖫰𖿰b; a◌̴◌𖫰𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING HIGH TONE, LATIN SMALL LETTER B
0061 16AF0 16FF0 0334 0062;0061 16AF0 0334 16FF0 0062;0061 16AF0 0334 16FF0 0062;0061 16AF0 0334 16FF0 0062;0061 16AF0 0334 16FF0 0062; # (a◌𖫰𖿰◌̴b; a◌𖫰◌̴𖿰b; a◌𖫰◌̴𖿰b; a◌𖫰◌̴𖿰b; a◌𖫰◌̴𖿰b; ) LATIN SMALL LETTER A, BASSA VAH COMBINING HIGH TONE, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B
0061 16FF0 0334 16AF1 0062;0061 0334 16AF1 16FF0 0062;0061 0334 16AF1 16FF0 0062;0061 0334 16AF1 16FF0 0062;0061 0334 16AF1 16FF0 0062; # (a𖿰◌̴◌𖫱b; a◌̴◌𖫱𖿰b; a◌̴◌𖫱𖿰b; a◌̴◌𖫱𖿰b; a◌̴◌𖫱𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING LOW TONE, LATIN SMALL LETTER B
@@ -18812,6 +18884,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1E029 0315 0300 05AE 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062;0061 05AE 1E029 0300 0315 0062; # (a◌𞀩◌̕◌̀◌֮b; a◌֮◌𞀩◌̀◌̕b; a◌֮◌𞀩◌̀◌̕b; a◌֮◌𞀩◌̀◌̕b; a◌֮◌𞀩◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER IOTATED BIG YUS, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E02A 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062;00E0 05AE 1E02A 0315 0062;0061 05AE 0300 1E02A 0315 0062; # (a◌̕◌̀◌֮◌𞀪b; à◌֮◌𞀪◌̕b; a◌֮◌̀◌𞀪◌̕b; à◌֮◌𞀪◌̕b; a◌֮◌̀◌𞀪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GLAGOLITIC LETTER FITA, LATIN SMALL LETTER B
0061 1E02A 0315 0300 05AE 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062;0061 05AE 1E02A 0300 0315 0062; # (a◌𞀪◌̕◌̀◌֮b; a◌֮◌𞀪◌̀◌̕b; a◌֮◌𞀪◌̀◌̕b; a◌֮◌𞀪◌̀◌̕b; a◌֮◌𞀪◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GLAGOLITIC LETTER FITA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E08F 0062;00E0 05AE 1E08F 0315 0062;0061 05AE 0300 1E08F 0315 0062;00E0 05AE 1E08F 0315 0062;0061 05AE 0300 1E08F 0315 0062; # (a◌̕◌̀◌֮◌𞂏b; à◌֮◌𞂏◌̕b; a◌֮◌̀◌𞂏◌̕b; à◌֮◌𞂏◌̕b; a◌֮◌̀◌𞂏◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I, LATIN SMALL LETTER B
+0061 1E08F 0315 0300 05AE 0062;0061 05AE 1E08F 0300 0315 0062;0061 05AE 1E08F 0300 0315 0062;0061 05AE 1E08F 0300 0315 0062;0061 05AE 1E08F 0300 0315 0062; # (a◌𞂏◌̕◌̀◌֮b; a◌֮◌𞂏◌̀◌̕b; a◌֮◌𞂏◌̀◌̕b; a◌֮◌𞂏◌̀◌̕b; a◌֮◌𞂏◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E130 0062;00E0 05AE 1E130 0315 0062;0061 05AE 0300 1E130 0315 0062;00E0 05AE 1E130 0315 0062;0061 05AE 0300 1E130 0315 0062; # (a◌̕◌̀◌֮◌𞄰b; à◌֮◌𞄰◌̕b; a◌֮◌̀◌𞄰◌̕b; à◌֮◌𞄰◌̕b; a◌֮◌̀◌𞄰◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-B, LATIN SMALL LETTER B
0061 1E130 0315 0300 05AE 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062;0061 05AE 1E130 0300 0315 0062; # (a◌𞄰◌̕◌̀◌֮b; a◌֮◌𞄰◌̀◌̕b; a◌֮◌𞄰◌̀◌̕b; a◌֮◌𞄰◌̀◌̕b; a◌֮◌𞄰◌̀◌̕b; ) LATIN SMALL LETTER A, NYIAKENG PUACHUE HMONG TONE-B, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E131 0062;00E0 05AE 1E131 0315 0062;0061 05AE 0300 1E131 0315 0062;00E0 05AE 1E131 0315 0062;0061 05AE 0300 1E131 0315 0062; # (a◌̕◌̀◌֮◌𞄱b; à◌֮◌𞄱◌̕b; a◌֮◌̀◌𞄱◌̕b; à◌֮◌𞄱◌̕b; a◌֮◌̀◌𞄱◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NYIAKENG PUACHUE HMONG TONE-M, LATIN SMALL LETTER B
@@ -18836,6 +18910,14 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE
0061 1E2EE 0315 0300 05AE 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062;0061 05AE 1E2EE 0300 0315 0062; # (a◌𞋮◌̕◌̀◌֮b; a◌֮◌𞋮◌̀◌̕b; a◌֮◌𞋮◌̀◌̕b; a◌֮◌𞋮◌̀◌̕b; a◌֮◌𞋮◌̀◌̕b; ) LATIN SMALL LETTER A, WANCHO TONE KOI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 0315 0300 05AE 1E2EF 0062;00E0 05AE 1E2EF 0315 0062;0061 05AE 0300 1E2EF 0315 0062;00E0 05AE 1E2EF 0315 0062;0061 05AE 0300 1E2EF 0315 0062; # (a◌̕◌̀◌֮◌𞋯b; à◌֮◌𞋯◌̕b; a◌֮◌̀◌𞋯◌̕b; à◌֮◌𞋯◌̕b; a◌֮◌̀◌𞋯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, WANCHO TONE KOINI, LATIN SMALL LETTER B
0061 1E2EF 0315 0300 05AE 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062;0061 05AE 1E2EF 0300 0315 0062; # (a◌𞋯◌̕◌̀◌֮b; a◌֮◌𞋯◌̀◌̕b; a◌֮◌𞋯◌̀◌̕b; a◌֮◌𞋯◌̀◌̕b; a◌֮◌𞋯◌̀◌̕b; ) LATIN SMALL LETTER A, WANCHO TONE KOINI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
+0061 035C 0315 0300 1E4EC 0062;00E0 0315 1E4EC 035C 0062;0061 0300 0315 1E4EC 035C 0062;00E0 0315 1E4EC 035C 0062;0061 0300 0315 1E4EC 035C 0062; # (a◌͜◌̕◌̀◌𞓬b; à◌̕◌𞓬◌͜b; a◌̀◌̕◌𞓬◌͜b; à◌̕◌𞓬◌͜b; a◌̀◌̕◌𞓬◌͜b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, NAG MUNDARI SIGN MUHOR, LATIN SMALL LETTER B
+0061 1E4EC 035C 0315 0300 0062;00E0 1E4EC 0315 035C 0062;0061 0300 1E4EC 0315 035C 0062;00E0 1E4EC 0315 035C 0062;0061 0300 1E4EC 0315 035C 0062; # (a◌𞓬◌͜◌̕◌̀b; à◌𞓬◌̕◌͜b; a◌̀◌𞓬◌̕◌͜b; à◌𞓬◌̕◌͜b; a◌̀◌𞓬◌̕◌͜b; ) LATIN SMALL LETTER A, NAG MUNDARI SIGN MUHOR, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
+0061 035C 0315 0300 1E4ED 0062;00E0 0315 1E4ED 035C 0062;0061 0300 0315 1E4ED 035C 0062;00E0 0315 1E4ED 035C 0062;0061 0300 0315 1E4ED 035C 0062; # (a◌͜◌̕◌̀◌𞓭b; à◌̕◌𞓭◌͜b; a◌̀◌̕◌𞓭◌͜b; à◌̕◌𞓭◌͜b; a◌̀◌̕◌𞓭◌͜b; ) LATIN SMALL LETTER A, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, NAG MUNDARI SIGN TOYOR, LATIN SMALL LETTER B
+0061 1E4ED 035C 0315 0300 0062;00E0 1E4ED 0315 035C 0062;0061 0300 1E4ED 0315 035C 0062;00E0 1E4ED 0315 035C 0062;0061 0300 1E4ED 0315 035C 0062; # (a◌𞓭◌͜◌̕◌̀b; à◌𞓭◌̕◌͜b; a◌̀◌𞓭◌̕◌͜b; à◌𞓭◌̕◌͜b; a◌̀◌𞓭◌̕◌͜b; ) LATIN SMALL LETTER A, NAG MUNDARI SIGN TOYOR, COMBINING DOUBLE BREVE BELOW, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, LATIN SMALL LETTER B
+0061 059A 0316 1DFA 1E4EE 0062;0061 1DFA 0316 1E4EE 059A 0062;0061 1DFA 0316 1E4EE 059A 0062;0061 1DFA 0316 1E4EE 059A 0062;0061 1DFA 0316 1E4EE 059A 0062; # (a◌֚◌̖◌᷺◌𞓮b; a◌᷺◌̖◌𞓮◌֚b; a◌᷺◌̖◌𞓮◌֚b; a◌᷺◌̖◌𞓮◌֚b; a◌᷺◌̖◌𞓮◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, NAG MUNDARI SIGN IKIR, LATIN SMALL LETTER B
+0061 1E4EE 059A 0316 1DFA 0062;0061 1DFA 1E4EE 0316 059A 0062;0061 1DFA 1E4EE 0316 059A 0062;0061 1DFA 1E4EE 0316 059A 0062;0061 1DFA 1E4EE 0316 059A 0062; # (a◌𞓮◌֚◌̖◌᷺b; a◌᷺◌𞓮◌̖◌֚b; a◌᷺◌𞓮◌̖◌֚b; a◌᷺◌𞓮◌̖◌֚b; a◌᷺◌𞓮◌̖◌֚b; ) LATIN SMALL LETTER A, NAG MUNDARI SIGN IKIR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
+0061 0315 0300 05AE 1E4EF 0062;00E0 05AE 1E4EF 0315 0062;0061 05AE 0300 1E4EF 0315 0062;00E0 05AE 1E4EF 0315 0062;0061 05AE 0300 1E4EF 0315 0062; # (a◌̕◌̀◌֮◌𞓯b; à◌֮◌𞓯◌̕b; a◌֮◌̀◌𞓯◌̕b; à◌֮◌𞓯◌̕b; a◌֮◌̀◌𞓯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NAG MUNDARI SIGN SUTUH, LATIN SMALL LETTER B
+0061 1E4EF 0315 0300 05AE 0062;0061 05AE 1E4EF 0300 0315 0062;0061 05AE 1E4EF 0300 0315 0062;0061 05AE 1E4EF 0300 0315 0062;0061 05AE 1E4EF 0300 0315 0062; # (a◌𞓯◌̕◌̀◌֮b; a◌֮◌𞓯◌̀◌̕b; a◌֮◌𞓯◌̀◌̕b; a◌֮◌𞓯◌̀◌̕b; a◌֮◌𞓯◌̀◌̕b; ) LATIN SMALL LETTER A, NAG MUNDARI SIGN SUTUH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B
0061 059A 0316 1DFA 1E8D0 0062;0061 1DFA 0316 1E8D0 059A 0062;0061 1DFA 0316 1E8D0 059A 0062;0061 1DFA 0316 1E8D0 059A 0062;0061 1DFA 0316 1E8D0 059A 0062; # (a◌֚◌̖◌᷺◌𞣐b; a◌᷺◌̖◌𞣐◌֚b; a◌᷺◌̖◌𞣐◌֚b; a◌᷺◌̖◌𞣐◌֚b; a◌᷺◌̖◌𞣐◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, MENDE KIKAKUI COMBINING NUMBER TEENS, LATIN SMALL LETTER B
0061 1E8D0 059A 0316 1DFA 0062;0061 1DFA 1E8D0 0316 059A 0062;0061 1DFA 1E8D0 0316 059A 0062;0061 1DFA 1E8D0 0316 059A 0062;0061 1DFA 1E8D0 0316 059A 0062; # (a◌𞣐◌֚◌̖◌᷺b; a◌᷺◌𞣐◌̖◌֚b; a◌᷺◌𞣐◌̖◌֚b; a◌᷺◌𞣐◌̖◌֚b; a◌᷺◌𞣐◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TEENS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B
0061 059A 0316 1DFA 1E8D1 0062;0061 1DFA 0316 1E8D1 059A 0062;0061 1DFA 0316 1E8D1 059A 0062;0061 1DFA 0316 1E8D1 059A 0062;0061 1DFA 0316 1E8D1 059A 0062; # (a◌֚◌̖◌᷺◌𞣑b; a◌᷺◌̖◌𞣑◌֚b; a◌᷺◌̖◌𞣑◌֚b; a◌᷺◌̖◌𞣑◌֚b; a◌᷺◌̖◌𞣑◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, MENDE KIKAKUI COMBINING NUMBER TENS, LATIN SMALL LETTER B
diff --git a/admin/unidata/PropertyValueAliases.txt b/admin/unidata/PropertyValueAliases.txt
index bdc13857dcb..9346fcf03ee 100644
--- a/admin/unidata/PropertyValueAliases.txt
+++ b/admin/unidata/PropertyValueAliases.txt
@@ -1,11 +1,11 @@
-# PropertyValueAliases-14.0.0.txt
-# Date: 2021-05-10, 21:08:53 GMT
-# © 2021 Unicode®, Inc.
+# PropertyValueAliases-15.0.0.txt
+# Date: 2022-08-05, 23:42:17 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
+# For documentation, see https://www.unicode.org/reports/tr44/
#
# This file contains aliases for property values used in the UCD.
# These names can be used for XML formats of UCD data, for regular-expression
@@ -90,6 +90,7 @@ age; 12.0 ; V12_0
age; 12.1 ; V12_1
age; 13.0 ; V13_0
age; 14.0 ; V14_0
+age; 15.0 ; V15_0
age; NA ; Unassigned
# Alphabetic (Alpha)
@@ -135,7 +136,6 @@ Bidi_M; Y ; Yes ; T
# Bidi_Mirroring_Glyph (bmg)
-# @missing: 0000..10FFFF; Bidi_Mirroring_Glyph; <none>
# Bidi_Paired_Bracket (bpb)
@@ -162,6 +162,7 @@ blk; Ancient_Symbols ; Ancient_Symbols
blk; Arabic ; Arabic
blk; Arabic_Ext_A ; Arabic_Extended_A
blk; Arabic_Ext_B ; Arabic_Extended_B
+blk; Arabic_Ext_C ; Arabic_Extended_C
blk; Arabic_Math ; Arabic_Mathematical_Alphabetic_Symbols
blk; Arabic_PF_A ; Arabic_Presentation_Forms_A ; Arabic_Presentation_Forms-A
blk; Arabic_PF_B ; Arabic_Presentation_Forms_B
@@ -206,6 +207,7 @@ blk; CJK_Ext_D ; CJK_Unified_Ideographs_Extension_D
blk; CJK_Ext_E ; CJK_Unified_Ideographs_Extension_E
blk; CJK_Ext_F ; CJK_Unified_Ideographs_Extension_F
blk; CJK_Ext_G ; CJK_Unified_Ideographs_Extension_G
+blk; CJK_Ext_H ; CJK_Unified_Ideographs_Extension_H
blk; CJK_Radicals_Sup ; CJK_Radicals_Supplement
blk; CJK_Strokes ; CJK_Strokes
blk; CJK_Symbols ; CJK_Symbols_And_Punctuation
@@ -223,10 +225,12 @@ blk; Cyrillic ; Cyrillic
blk; Cyrillic_Ext_A ; Cyrillic_Extended_A
blk; Cyrillic_Ext_B ; Cyrillic_Extended_B
blk; Cyrillic_Ext_C ; Cyrillic_Extended_C
+blk; Cyrillic_Ext_D ; Cyrillic_Extended_D
blk; Cyrillic_Sup ; Cyrillic_Supplement ; Cyrillic_Supplementary
blk; Deseret ; Deseret
blk; Devanagari ; Devanagari
blk; Devanagari_Ext ; Devanagari_Extended
+blk; Devanagari_Ext_A ; Devanagari_Extended_A
blk; Diacriticals ; Combining_Diacritical_Marks
blk; Diacriticals_Ext ; Combining_Diacritical_Marks_Extended
blk; Diacriticals_For_Symbols ; Combining_Diacritical_Marks_For_Symbols; Combining_Marks_For_Symbols
@@ -288,6 +292,7 @@ blk; Jamo_Ext_A ; Hangul_Jamo_Extended_A
blk; Jamo_Ext_B ; Hangul_Jamo_Extended_B
blk; Javanese ; Javanese
blk; Kaithi ; Kaithi
+blk; Kaktovik_Numerals ; Kaktovik_Numerals
blk; Kana_Ext_A ; Kana_Extended_A
blk; Kana_Ext_B ; Kana_Extended_B
blk; Kana_Sup ; Kana_Supplement
@@ -296,6 +301,7 @@ blk; Kangxi ; Kangxi_Radicals
blk; Kannada ; Kannada
blk; Katakana ; Katakana
blk; Katakana_Ext ; Katakana_Phonetic_Extensions
+blk; Kawi ; Kawi
blk; Kayah_Li ; Kayah_Li
blk; Kharoshthi ; Kharoshthi
blk; Khitan_Small_Script ; Khitan_Small_Script
@@ -360,6 +366,7 @@ blk; Myanmar ; Myanmar
blk; Myanmar_Ext_A ; Myanmar_Extended_A
blk; Myanmar_Ext_B ; Myanmar_Extended_B
blk; Nabataean ; Nabataean
+blk; Nag_Mundari ; Nag_Mundari
blk; Nandinagari ; Nandinagari
blk; NB ; No_Block
blk; New_Tai_Lue ; New_Tai_Lue
@@ -663,7 +670,6 @@ EPres; Y ; Yes ; T
# Equivalent_Unified_Ideograph (EqUIdeo)
-# @missing: 0000..10FFFF; Equivalent_Unified_Ideograph; <none>
# Expands_On_NFC (XO_NFC)
@@ -1143,7 +1149,6 @@ NFD_QC; Y ; Yes
# NFKC_Casefold (NFKC_CF)
-# @missing: 0000..10FFFF; NFKC_Casefold; <code point>
# NFKC_Quick_Check (NFKC_QC)
@@ -1313,6 +1318,7 @@ sc ; Ital ; Old_Italic
sc ; Java ; Javanese
sc ; Kali ; Kayah_Li
sc ; Kana ; Katakana
+sc ; Kawi ; Kawi
sc ; Khar ; Kharoshthi
sc ; Khmr ; Khmer
sc ; Khoj ; Khojki
@@ -1345,6 +1351,7 @@ sc ; Mroo ; Mro
sc ; Mtei ; Meetei_Mayek
sc ; Mult ; Multani
sc ; Mymr ; Myanmar
+sc ; Nagm ; Nag_Mundari
sc ; Nand ; Nandinagari
sc ; Narb ; Old_North_Arabian
sc ; Nbat ; Nabataean
@@ -1418,7 +1425,6 @@ sc ; Zzzz ; Unknown
# Script_Extensions (scx)
-# @missing: 0000..10FFFF; Script_Extensions; <script>
# Sentence_Break (SB)
diff --git a/admin/unidata/README b/admin/unidata/README
index 2da01402b70..2d421dfb6bf 100644
--- a/admin/unidata/README
+++ b/admin/unidata/README
@@ -6,31 +6,31 @@ copyright.html.
The names, URLs, and dates for these files are as follows.
BidiBrackets.txt
-http://www.unicode.org/Public/UNIDATA/BidiBrackets.txt
+https://www.unicode.org/Public/UNIDATA/BidiBrackets.txt
2021-06-30
BidiMirroring.txt
-http://www.unicode.org/Public/UNIDATA/BidiMirroring.txt
+https://www.unicode.org/Public/UNIDATA/BidiMirroring.txt
2021-08-08
Blocks.txt
-http://www.unicode.org/Public/8.0.0/ucd/Blocks.txt
+https://www.unicode.org/Public/8.0.0/ucd/Blocks.txt
2021-01-22
IVD_Sequences.txt
-http://www.unicode.org/ivd/
+https://www.unicode.org/ivd/
2020-11-06
NormalizationTest.txt
-http://www.unicode.org/Public/UNIDATA/NormalizationTest.txt
+https://www.unicode.org/Public/UNIDATA/NormalizationTest.txt
2021-05-28
SpecialCasing.txt
-http://unicode.org/Public/UNIDATA/SpecialCasing.txt
+https://unicode.org/Public/UNIDATA/SpecialCasing.txt
2021-03-08
UnicodeData.txt
-http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
+https://www.unicode.org/Public/UNIDATA/UnicodeData.txt
2021-07-06
emoji-data.txt
diff --git a/admin/unidata/ScriptExtensions.txt b/admin/unidata/ScriptExtensions.txt
index 3f5cd1c0dbb..2f5a1727e33 100644
--- a/admin/unidata/ScriptExtensions.txt
+++ b/admin/unidata/ScriptExtensions.txt
@@ -1,11 +1,11 @@
-# ScriptExtensions-14.0.0.txt
-# Date: 2021-06-04, 02:19:38 GMT
-# © 2021 Unicode®, Inc.
+# ScriptExtensions-15.0.0.txt
+# Date: 2022-02-02, 00:57:11 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
+# For documentation, see https://www.unicode.org/reports/tr44/
#
# The Script_Extensions property indicates which characters are commonly used
# with more than one script, but with a limited number of scripts.
diff --git a/admin/unidata/Scripts.txt b/admin/unidata/Scripts.txt
index a1383730119..2b138bffb88 100644
--- a/admin/unidata/Scripts.txt
+++ b/admin/unidata/Scripts.txt
@@ -1,11 +1,11 @@
-# Scripts-14.0.0.txt
-# Date: 2021-07-10, 00:35:31 GMT
-# © 2021 Unicode®, Inc.
+# Scripts-15.0.0.txt
+# Date: 2022-04-26, 23:15:02 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
+# For documentation, see https://www.unicode.org/reports/tr44/
# For more information, see:
# UAX #24, Unicode Script Property: https://www.unicode.org/reports/tr24/
# Especially the sections:
@@ -532,6 +532,7 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR
1D183..1D184 ; Common # So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN
1D18C..1D1A9 ; Common # So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH
1D1AE..1D1EA ; Common # So [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON
+1D2C0..1D2D3 ; Common # No [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN
1D2E0..1D2F3 ; Common # No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN
1D300..1D356 ; Common # So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
1D360..1D378 ; Common # No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE
@@ -601,10 +602,10 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR
1F300..1F3FA ; Common # So [251] CYCLONE..AMPHORA
1F3FB..1F3FF ; Common # Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6
1F400..1F6D7 ; Common # So [728] RAT..ELEVATOR
-1F6DD..1F6EC ; Common # So [16] PLAYGROUND SLIDE..AIRPLANE ARRIVING
+1F6DC..1F6EC ; Common # So [17] WIRELESS..AIRPLANE ARRIVING
1F6F0..1F6FC ; Common # So [13] SATELLITE..ROLLER SKATE
-1F700..1F773 ; Common # So [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE
-1F780..1F7D8 ; Common # So [89] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NEGATIVE CIRCLED SQUARE
+1F700..1F776 ; Common # So [119] ALCHEMICAL SYMBOL FOR QUINTESSENCE..LUNAR ECLIPSE
+1F77B..1F7D9 ; Common # So [95] HAUMEA..NINE POINTED WHITE STAR
1F7E0..1F7EB ; Common # So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE
1F7F0 ; Common # So HEAVY EQUALS SIGN
1F800..1F80B ; Common # So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD
@@ -615,22 +616,20 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR
1F8B0..1F8B1 ; Common # So [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST
1F900..1FA53 ; Common # So [340] CIRCLED CROSS FORMEE WITH FOUR DOTS..BLACK CHESS KNIGHT-BISHOP
1FA60..1FA6D ; Common # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER
-1FA70..1FA74 ; Common # So [5] BALLET SHOES..THONG SANDAL
-1FA78..1FA7C ; Common # So [5] DROP OF BLOOD..CRUTCH
-1FA80..1FA86 ; Common # So [7] YO-YO..NESTING DOLLS
-1FA90..1FAAC ; Common # So [29] RINGED PLANET..HAMSA
-1FAB0..1FABA ; Common # So [11] FLY..NEST WITH EGGS
-1FAC0..1FAC5 ; Common # So [6] ANATOMICAL HEART..PERSON WITH CROWN
-1FAD0..1FAD9 ; Common # So [10] BLUEBERRIES..JAR
-1FAE0..1FAE7 ; Common # So [8] MELTING FACE..BUBBLES
-1FAF0..1FAF6 ; Common # So [7] HAND WITH INDEX FINGER AND THUMB CROSSED..HEART HANDS
+1FA70..1FA7C ; Common # So [13] BALLET SHOES..CRUTCH
+1FA80..1FA88 ; Common # So [9] YO-YO..FLUTE
+1FA90..1FABD ; Common # So [46] RINGED PLANET..WING
+1FABF..1FAC5 ; Common # So [7] GOOSE..PERSON WITH CROWN
+1FACE..1FADB ; Common # So [14] MOOSE..PEA POD
+1FAE0..1FAE8 ; Common # So [9] MELTING FACE..SHAKING FACE
+1FAF0..1FAF8 ; Common # So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND
1FB00..1FB92 ; Common # So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK
1FB94..1FBCA ; Common # So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON
1FBF0..1FBF9 ; Common # Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE
E0001 ; Common # Cf LANGUAGE TAG
E0020..E007F ; Common # Cf [96] TAG SPACE..CANCEL TAG
-# Total code points: 8252
+# Total code points: 8301
# ================================================
@@ -697,8 +696,9 @@ FF41..FF5A ; Latin # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN
1DF00..1DF09 ; Latin # L& [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK
1DF0A ; Latin # Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK
1DF0B..1DF1E ; Latin # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL
+1DF25..1DF2A ; Latin # L& [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK
-# Total code points: 1475
+# Total code points: 1481
# ================================================
@@ -784,8 +784,10 @@ A680..A69B ; Cyrillic # L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL
A69C..A69D ; Cyrillic # Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN
A69E..A69F ; Cyrillic # Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
FE2E..FE2F ; Cyrillic # Mn [2] COMBINING CYRILLIC TITLO LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
+1E030..1E06D ; Cyrillic # Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE
+1E08F ; Cyrillic # Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
-# Total code points: 443
+# Total code points: 506
# ================================================
@@ -883,6 +885,7 @@ FDFD..FDFF ; Arabic # So [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM.
FE70..FE74 ; Arabic # Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM
FE76..FEFC ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM
10E60..10E7E ; Arabic # No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS
+10EFD..10EFF ; Arabic # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA
1EE00..1EE03 ; Arabic # Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL
1EE05..1EE1F ; Arabic # Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF
1EE21..1EE22 ; Arabic # Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM
@@ -918,7 +921,7 @@ FE76..FEFC ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LA
1EEAB..1EEBB ; Arabic # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
1EEF0..1EEF1 ; Arabic # Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL
-# Total code points: 1365
+# Total code points: 1368
# ================================================
@@ -970,8 +973,9 @@ A8FB ; Devanagari # Lo DEVANAGARI HEADSTROKE
A8FC ; Devanagari # Po DEVANAGARI SIGN SIDDHAM
A8FD..A8FE ; Devanagari # Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY
A8FF ; Devanagari # Mn DEVANAGARI VOWEL SIGN AY
+11B00..11B09 ; Devanagari # Po [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU
-# Total code points: 154
+# Total code points: 164
# ================================================
@@ -1182,8 +1186,9 @@ A8FF ; Devanagari # Mn DEVANAGARI VOWEL SIGN AY
0CE2..0CE3 ; Kannada # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
0CE6..0CEF ; Kannada # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
0CF1..0CF2 ; Kannada # Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
+0CF3 ; Kannada # Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT
-# Total code points: 90
+# Total code points: 91
# ================================================
@@ -1263,11 +1268,11 @@ A8FF ; Devanagari # Mn DEVANAGARI VOWEL SIGN AY
0EBD ; Lao # Lo LAO SEMIVOWEL SIGN NYO
0EC0..0EC4 ; Lao # Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
0EC6 ; Lao # Lm LAO KO LA
-0EC8..0ECD ; Lao # Mn [6] LAO TONE MAI EK..LAO NIGGAHITA
+0EC8..0ECE ; Lao # Mn [7] LAO TONE MAI EK..LAO YAMAKKAN
0ED0..0ED9 ; Lao # Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE
0EDC..0EDF ; Lao # Lo [4] LAO HO NO..LAO LETTER KHMU NYO
-# Total code points: 82
+# Total code points: 83
# ================================================
@@ -1532,10 +1537,11 @@ AB70..ABBF ; Cherokee # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETT
309D..309E ; Hiragana # Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
309F ; Hiragana # Lo HIRAGANA DIGRAPH YORI
1B001..1B11F ; Hiragana # Lo [287] HIRAGANA LETTER ARCHAIC YE..HIRAGANA LETTER ARCHAIC WU
+1B132 ; Hiragana # Lo HIRAGANA LETTER SMALL KO
1B150..1B152 ; Hiragana # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
1F200 ; Hiragana # So SQUARE HIRAGANA HOKA
-# Total code points: 380
+# Total code points: 381
# ================================================
@@ -1552,9 +1558,10 @@ FF71..FF9D ; Katakana # Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAK
1AFFD..1AFFE ; Katakana # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8
1B000 ; Katakana # Lo KATAKANA LETTER ARCHAIC E
1B120..1B122 ; Katakana # Lo [3] KATAKANA LETTER ARCHAIC YI..KATAKANA LETTER ARCHAIC WU
+1B155 ; Katakana # Lo KATAKANA LETTER SMALL KO
1B164..1B167 ; Katakana # Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
-# Total code points: 320
+# Total code points: 321
# ================================================
@@ -1582,14 +1589,15 @@ FA70..FAD9 ; Han # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILI
16FE3 ; Han # Lm OLD CHINESE ITERATION MARK
16FF0..16FF1 ; Han # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
20000..2A6DF ; Han # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF
-2A700..2B738 ; Han # Lo [4153] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B738
+2A700..2B739 ; Han # Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739
2B740..2B81D ; Han # Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
2B820..2CEA1 ; Han # Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
2CEB0..2EBE0 ; Han # Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
2F800..2FA1D ; Han # Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
30000..3134A ; Han # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
+31350..323AF ; Han # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF
-# Total code points: 94215
+# Total code points: 98408
# ================================================
@@ -2093,10 +2101,13 @@ AADE..AADF ; Tai_Viet # Po [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI
# ================================================
-13000..1342E ; Egyptian_Hieroglyphs # Lo [1071] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH AA032
-13430..13438 ; Egyptian_Hieroglyphs # Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT
+13000..1342F ; Egyptian_Hieroglyphs # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D
+13430..1343F ; Egyptian_Hieroglyphs # Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE
+13440 ; Egyptian_Hieroglyphs # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY
+13441..13446 ; Egyptian_Hieroglyphs # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN
+13447..13455 ; Egyptian_Hieroglyphs # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED
-# Total code points: 1080
+# Total code points: 1110
# ================================================
@@ -2440,8 +2451,10 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI
11236..11237 ; Khojki # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
11238..1123D ; Khojki # Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN
1123E ; Khojki # Mn KHOJKI SIGN SUKUN
+1123F..11240 ; Khojki # Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I
+11241 ; Khojki # Mn KHOJKI VOWEL SIGN VOCALIC R
-# Total code points: 62
+# Total code points: 65
# ================================================
@@ -2988,4 +3001,31 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI
# Total code points: 70
+# ================================================
+
+11F00..11F01 ; Kawi # Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA
+11F02 ; Kawi # Lo KAWI SIGN REPHA
+11F03 ; Kawi # Mc KAWI SIGN VISARGA
+11F04..11F10 ; Kawi # Lo [13] KAWI LETTER A..KAWI LETTER O
+11F12..11F33 ; Kawi # Lo [34] KAWI LETTER KA..KAWI LETTER JNYA
+11F34..11F35 ; Kawi # Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA
+11F36..11F3A ; Kawi # Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R
+11F3E..11F3F ; Kawi # Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI
+11F40 ; Kawi # Mn KAWI VOWEL SIGN EU
+11F41 ; Kawi # Mc KAWI SIGN KILLER
+11F42 ; Kawi # Mn KAWI CONJOINER
+11F43..11F4F ; Kawi # Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL
+11F50..11F59 ; Kawi # Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE
+
+# Total code points: 86
+
+# ================================================
+
+1E4D0..1E4EA ; Nag_Mundari # Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL
+1E4EB ; Nag_Mundari # Lm NAG MUNDARI SIGN OJOD
+1E4EC..1E4EF ; Nag_Mundari # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH
+1E4F0..1E4F9 ; Nag_Mundari # Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE
+
+# Total code points: 42
+
# EOF
diff --git a/admin/unidata/SpecialCasing.txt b/admin/unidata/SpecialCasing.txt
index 1c2e968a8c4..08d04fa9421 100644
--- a/admin/unidata/SpecialCasing.txt
+++ b/admin/unidata/SpecialCasing.txt
@@ -1,11 +1,11 @@
-# SpecialCasing-14.0.0.txt
-# Date: 2021-03-08, 19:35:55 GMT
-# © 2021 Unicode®, Inc.
+# SpecialCasing-15.0.0.txt
+# Date: 2022-02-02, 23:35:52 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
+# For documentation, see https://www.unicode.org/reports/tr44/
#
# Special Casing
#
diff --git a/admin/unidata/UnicodeData.txt b/admin/unidata/UnicodeData.txt
index b5abef7ed43..ea963a7162c 100644
--- a/admin/unidata/UnicodeData.txt
+++ b/admin/unidata/UnicodeData.txt
@@ -2975,6 +2975,7 @@
0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;
0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;
+0CF3;KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT;Mc;0;L;;;;;N;;;;;
0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;
0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
@@ -3339,6 +3340,7 @@
0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;;
0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;;
0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;;
+0ECE;LAO YAMAKKAN;Mn;0;NSM;;;;;N;;;;;
0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -19393,6 +19395,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
10EAD;YEZIDI HYPHENATION MARK;Pd;0;R;;;;;N;;;;;
10EB0;YEZIDI LETTER LAM WITH DOT ABOVE;Lo;0;R;;;;;N;;;;;
10EB1;YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE;Lo;0;R;;;;;N;;;;;
+10EFD;ARABIC SMALL LOW WORD SAKTA;Mn;220;NSM;;;;;N;;;;;
+10EFE;ARABIC SMALL LOW WORD QASR;Mn;220;NSM;;;;;N;;;;;
+10EFF;ARABIC SMALL LOW WORD MADDA;Mn;220;NSM;;;;;N;;;;;
10F00;OLD SOGDIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;
10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;;
10F02;OLD SOGDIAN LETTER BETH;Lo;0;R;;;;;N;;;;;
@@ -20058,6 +20063,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1123C;KHOJKI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;
1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
1123E;KHOJKI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;;
+1123F;KHOJKI LETTER QA;Lo;0;L;;;;;N;;;;;
+11240;KHOJKI LETTER SHORT I;Lo;0;L;;;;;N;;;;;
+11241;KHOJKI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
11280;MULTANI LETTER A;Lo;0;L;;;;;N;;;;;
11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;;
11282;MULTANI LETTER U;Lo;0;L;;;;;N;;;;;
@@ -21256,6 +21264,16 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
11AF6;PAU CIN HAU LOW-FALLING TONE LONG FINAL;Lo;0;L;;;;;N;;;;;
11AF7;PAU CIN HAU LOW-FALLING TONE FINAL;Lo;0;L;;;;;N;;;;;
11AF8;PAU CIN HAU GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;;
+11B00;DEVANAGARI HEAD MARK;Po;0;L;;;;;N;;;;;
+11B01;DEVANAGARI HEAD MARK WITH HEADSTROKE;Po;0;L;;;;;N;;;;;
+11B02;DEVANAGARI SIGN BHALE;Po;0;L;;;;;N;;;;;
+11B03;DEVANAGARI SIGN BHALE WITH HOOK;Po;0;L;;;;;N;;;;;
+11B04;DEVANAGARI SIGN EXTENDED BHALE;Po;0;L;;;;;N;;;;;
+11B05;DEVANAGARI SIGN EXTENDED BHALE WITH HOOK;Po;0;L;;;;;N;;;;;
+11B06;DEVANAGARI SIGN WESTERN FIVE-LIKE BHALE;Po;0;L;;;;;N;;;;;
+11B07;DEVANAGARI SIGN WESTERN NINE-LIKE BHALE;Po;0;L;;;;;N;;;;;
+11B08;DEVANAGARI SIGN REVERSED NINE-LIKE BHALE;Po;0;L;;;;;N;;;;;
+11B09;DEVANAGARI SIGN MINDU;Po;0;L;;;;;N;;;;;
11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;;
11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;;
11C02;BHAIKSUKI LETTER I;Lo;0;L;;;;;N;;;;;
@@ -21584,6 +21602,92 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;;
11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;;
+11F00;KAWI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
+11F01;KAWI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
+11F02;KAWI SIGN REPHA;Lo;0;L;;;;;N;;;;;
+11F03;KAWI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
+11F04;KAWI LETTER A;Lo;0;L;;;;;N;;;;;
+11F05;KAWI LETTER AA;Lo;0;L;;;;;N;;;;;
+11F06;KAWI LETTER I;Lo;0;L;;;;;N;;;;;
+11F07;KAWI LETTER II;Lo;0;L;;;;;N;;;;;
+11F08;KAWI LETTER U;Lo;0;L;;;;;N;;;;;
+11F09;KAWI LETTER UU;Lo;0;L;;;;;N;;;;;
+11F0A;KAWI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
+11F0B;KAWI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
+11F0C;KAWI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
+11F0D;KAWI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
+11F0E;KAWI LETTER E;Lo;0;L;;;;;N;;;;;
+11F0F;KAWI LETTER AI;Lo;0;L;;;;;N;;;;;
+11F10;KAWI LETTER O;Lo;0;L;;;;;N;;;;;
+11F12;KAWI LETTER KA;Lo;0;L;;;;;N;;;;;
+11F13;KAWI LETTER KHA;Lo;0;L;;;;;N;;;;;
+11F14;KAWI LETTER GA;Lo;0;L;;;;;N;;;;;
+11F15;KAWI LETTER GHA;Lo;0;L;;;;;N;;;;;
+11F16;KAWI LETTER NGA;Lo;0;L;;;;;N;;;;;
+11F17;KAWI LETTER CA;Lo;0;L;;;;;N;;;;;
+11F18;KAWI LETTER CHA;Lo;0;L;;;;;N;;;;;
+11F19;KAWI LETTER JA;Lo;0;L;;;;;N;;;;;
+11F1A;KAWI LETTER JHA;Lo;0;L;;;;;N;;;;;
+11F1B;KAWI LETTER NYA;Lo;0;L;;;;;N;;;;;
+11F1C;KAWI LETTER TTA;Lo;0;L;;;;;N;;;;;
+11F1D;KAWI LETTER TTHA;Lo;0;L;;;;;N;;;;;
+11F1E;KAWI LETTER DDA;Lo;0;L;;;;;N;;;;;
+11F1F;KAWI LETTER DDHA;Lo;0;L;;;;;N;;;;;
+11F20;KAWI LETTER NNA;Lo;0;L;;;;;N;;;;;
+11F21;KAWI LETTER TA;Lo;0;L;;;;;N;;;;;
+11F22;KAWI LETTER THA;Lo;0;L;;;;;N;;;;;
+11F23;KAWI LETTER DA;Lo;0;L;;;;;N;;;;;
+11F24;KAWI LETTER DHA;Lo;0;L;;;;;N;;;;;
+11F25;KAWI LETTER NA;Lo;0;L;;;;;N;;;;;
+11F26;KAWI LETTER PA;Lo;0;L;;;;;N;;;;;
+11F27;KAWI LETTER PHA;Lo;0;L;;;;;N;;;;;
+11F28;KAWI LETTER BA;Lo;0;L;;;;;N;;;;;
+11F29;KAWI LETTER BHA;Lo;0;L;;;;;N;;;;;
+11F2A;KAWI LETTER MA;Lo;0;L;;;;;N;;;;;
+11F2B;KAWI LETTER YA;Lo;0;L;;;;;N;;;;;
+11F2C;KAWI LETTER RA;Lo;0;L;;;;;N;;;;;
+11F2D;KAWI LETTER LA;Lo;0;L;;;;;N;;;;;
+11F2E;KAWI LETTER WA;Lo;0;L;;;;;N;;;;;
+11F2F;KAWI LETTER SHA;Lo;0;L;;;;;N;;;;;
+11F30;KAWI LETTER SSA;Lo;0;L;;;;;N;;;;;
+11F31;KAWI LETTER SA;Lo;0;L;;;;;N;;;;;
+11F32;KAWI LETTER HA;Lo;0;L;;;;;N;;;;;
+11F33;KAWI LETTER JNYA;Lo;0;L;;;;;N;;;;;
+11F34;KAWI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
+11F35;KAWI VOWEL SIGN ALTERNATE AA;Mc;0;L;;;;;N;;;;;
+11F36;KAWI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
+11F37;KAWI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
+11F38;KAWI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
+11F39;KAWI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
+11F3A;KAWI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
+11F3E;KAWI VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
+11F3F;KAWI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
+11F40;KAWI VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;;
+11F41;KAWI SIGN KILLER;Mc;9;L;;;;;N;;;;;
+11F42;KAWI CONJOINER;Mn;9;NSM;;;;;N;;;;;
+11F43;KAWI DANDA;Po;0;L;;;;;N;;;;;
+11F44;KAWI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
+11F45;KAWI PUNCTUATION SECTION MARKER;Po;0;L;;;;;N;;;;;
+11F46;KAWI PUNCTUATION ALTERNATE SECTION MARKER;Po;0;L;;;;;N;;;;;
+11F47;KAWI PUNCTUATION FLOWER;Po;0;L;;;;;N;;;;;
+11F48;KAWI PUNCTUATION SPACE FILLER;Po;0;L;;;;;N;;;;;
+11F49;KAWI PUNCTUATION DOT;Po;0;L;;;;;N;;;;;
+11F4A;KAWI PUNCTUATION DOUBLE DOT;Po;0;L;;;;;N;;;;;
+11F4B;KAWI PUNCTUATION TRIPLE DOT;Po;0;L;;;;;N;;;;;
+11F4C;KAWI PUNCTUATION CIRCLE;Po;0;L;;;;;N;;;;;
+11F4D;KAWI PUNCTUATION FILLED CIRCLE;Po;0;L;;;;;N;;;;;
+11F4E;KAWI PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;;
+11F4F;KAWI PUNCTUATION CLOSING SPIRAL;Po;0;L;;;;;N;;;;;
+11F50;KAWI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+11F51;KAWI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+11F52;KAWI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+11F53;KAWI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+11F54;KAWI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+11F55;KAWI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+11F56;KAWI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+11F57;KAWI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+11F58;KAWI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+11F59;KAWI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
11FB0;LISU LETTER YHA;Lo;0;L;;;;;N;;;;;
11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;;
11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;;
@@ -24040,6 +24144,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;;
1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;;
1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;;
+1342F;EGYPTIAN HIEROGLYPH V011D;Lo;0;L;;;;;N;;;;;
13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;;
13431;EGYPTIAN HIEROGLYPH HORIZONTAL JOINER;Cf;0;L;;;;;N;;;;;
13432;EGYPTIAN HIEROGLYPH INSERT AT TOP START;Cf;0;L;;;;;N;;;;;
@@ -24049,6 +24154,35 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;;
13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;;
13438;EGYPTIAN HIEROGLYPH END SEGMENT;Cf;0;L;;;;;N;;;;;
+13439;EGYPTIAN HIEROGLYPH INSERT AT MIDDLE;Cf;0;L;;;;;N;;;;;
+1343A;EGYPTIAN HIEROGLYPH INSERT AT TOP;Cf;0;L;;;;;N;;;;;
+1343B;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM;Cf;0;L;;;;;N;;;;;
+1343C;EGYPTIAN HIEROGLYPH BEGIN ENCLOSURE;Cf;0;L;;;;;N;;;;;
+1343D;EGYPTIAN HIEROGLYPH END ENCLOSURE;Cf;0;L;;;;;N;;;;;
+1343E;EGYPTIAN HIEROGLYPH BEGIN WALLED ENCLOSURE;Cf;0;L;;;;;N;;;;;
+1343F;EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE;Cf;0;L;;;;;N;;;;;
+13440;EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY;Mn;0;NSM;;;;;N;;;;;
+13441;EGYPTIAN HIEROGLYPH FULL BLANK;Lo;0;L;;;;;N;;;;;
+13442;EGYPTIAN HIEROGLYPH HALF BLANK;Lo;0;L;;;;;N;;;;;
+13443;EGYPTIAN HIEROGLYPH LOST SIGN;Lo;0;L;;;;;N;;;;;
+13444;EGYPTIAN HIEROGLYPH HALF LOST SIGN;Lo;0;L;;;;;N;;;;;
+13445;EGYPTIAN HIEROGLYPH TALL LOST SIGN;Lo;0;L;;;;;N;;;;;
+13446;EGYPTIAN HIEROGLYPH WIDE LOST SIGN;Lo;0;L;;;;;N;;;;;
+13447;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START;Mn;0;NSM;;;;;N;;;;;
+13448;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM START;Mn;0;NSM;;;;;N;;;;;
+13449;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START;Mn;0;NSM;;;;;N;;;;;
+1344A;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP END;Mn;0;NSM;;;;;N;;;;;
+1344B;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP;Mn;0;NSM;;;;;N;;;;;
+1344C;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM START AND TOP END;Mn;0;NSM;;;;;N;;;;;
+1344D;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START AND TOP;Mn;0;NSM;;;;;N;;;;;
+1344E;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM END;Mn;0;NSM;;;;;N;;;;;
+1344F;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START AND BOTTOM END;Mn;0;NSM;;;;;N;;;;;
+13450;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM;Mn;0;NSM;;;;;N;;;;;
+13451;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT START AND BOTTOM;Mn;0;NSM;;;;;N;;;;;
+13452;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT END;Mn;0;NSM;;;;;N;;;;;
+13453;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP AND END;Mn;0;NSM;;;;;N;;;;;
+13454;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM AND END;Mn;0;NSM;;;;;N;;;;;
+13455;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED;Mn;0;NSM;;;;;N;;;;;
14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;
14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;
14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;
@@ -27289,9 +27423,11 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1B120;KATAKANA LETTER ARCHAIC YI;Lo;0;L;;;;;N;;;;;
1B121;KATAKANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;
1B122;KATAKANA LETTER ARCHAIC WU;Lo;0;L;;;;;N;;;;;
+1B132;HIRAGANA LETTER SMALL KO;Lo;0;L;;;;;N;;;;;
1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;
+1B155;KATAKANA LETTER SMALL KO;Lo;0;L;;;;;N;;;;;
1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;
1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;
1B166;KATAKANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;
@@ -28573,6 +28709,26 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;;
1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;;
1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;;
+1D2C0;KAKTOVIK NUMERAL ZERO;No;0;L;;;;0;N;;;;;
+1D2C1;KAKTOVIK NUMERAL ONE;No;0;L;;;;1;N;;;;;
+1D2C2;KAKTOVIK NUMERAL TWO;No;0;L;;;;2;N;;;;;
+1D2C3;KAKTOVIK NUMERAL THREE;No;0;L;;;;3;N;;;;;
+1D2C4;KAKTOVIK NUMERAL FOUR;No;0;L;;;;4;N;;;;;
+1D2C5;KAKTOVIK NUMERAL FIVE;No;0;L;;;;5;N;;;;;
+1D2C6;KAKTOVIK NUMERAL SIX;No;0;L;;;;6;N;;;;;
+1D2C7;KAKTOVIK NUMERAL SEVEN;No;0;L;;;;7;N;;;;;
+1D2C8;KAKTOVIK NUMERAL EIGHT;No;0;L;;;;8;N;;;;;
+1D2C9;KAKTOVIK NUMERAL NINE;No;0;L;;;;9;N;;;;;
+1D2CA;KAKTOVIK NUMERAL TEN;No;0;L;;;;10;N;;;;;
+1D2CB;KAKTOVIK NUMERAL ELEVEN;No;0;L;;;;11;N;;;;;
+1D2CC;KAKTOVIK NUMERAL TWELVE;No;0;L;;;;12;N;;;;;
+1D2CD;KAKTOVIK NUMERAL THIRTEEN;No;0;L;;;;13;N;;;;;
+1D2CE;KAKTOVIK NUMERAL FOURTEEN;No;0;L;;;;14;N;;;;;
+1D2CF;KAKTOVIK NUMERAL FIFTEEN;No;0;L;;;;15;N;;;;;
+1D2D0;KAKTOVIK NUMERAL SIXTEEN;No;0;L;;;;16;N;;;;;
+1D2D1;KAKTOVIK NUMERAL SEVENTEEN;No;0;L;;;;17;N;;;;;
+1D2D2;KAKTOVIK NUMERAL EIGHTEEN;No;0;L;;;;18;N;;;;;
+1D2D3;KAKTOVIK NUMERAL NINETEEN;No;0;L;;;;19;N;;;;;
1D2E0;MAYAN NUMERAL ZERO;No;0;L;;;;0;N;;;;;
1D2E1;MAYAN NUMERAL ONE;No;0;L;;;;1;N;;;;;
1D2E2;MAYAN NUMERAL TWO;No;0;L;;;;2;N;;;;;
@@ -30404,6 +30560,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1DF1C;LATIN SMALL LETTER TESH DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
1DF1D;LATIN SMALL LETTER C WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
1DF1E;LATIN SMALL LETTER S WITH CURL;Ll;0;L;;;;;N;;;;;
+1DF25;LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
+1DF26;LATIN SMALL LETTER L WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
+1DF27;LATIN SMALL LETTER N WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
+1DF28;LATIN SMALL LETTER R WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
+1DF29;LATIN SMALL LETTER S WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
+1DF2A;LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK;Ll;0;L;;;;;N;;;;;
1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;;
1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;;
1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;;
@@ -30442,6 +30604,69 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;;
1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;
+1E030;MODIFIER LETTER CYRILLIC SMALL A;Lm;0;L;<super> 0430;;;;N;;;;;
+1E031;MODIFIER LETTER CYRILLIC SMALL BE;Lm;0;L;<super> 0431;;;;N;;;;;
+1E032;MODIFIER LETTER CYRILLIC SMALL VE;Lm;0;L;<super> 0432;;;;N;;;;;
+1E033;MODIFIER LETTER CYRILLIC SMALL GHE;Lm;0;L;<super> 0433;;;;N;;;;;
+1E034;MODIFIER LETTER CYRILLIC SMALL DE;Lm;0;L;<super> 0434;;;;N;;;;;
+1E035;MODIFIER LETTER CYRILLIC SMALL IE;Lm;0;L;<super> 0435;;;;N;;;;;
+1E036;MODIFIER LETTER CYRILLIC SMALL ZHE;Lm;0;L;<super> 0436;;;;N;;;;;
+1E037;MODIFIER LETTER CYRILLIC SMALL ZE;Lm;0;L;<super> 0437;;;;N;;;;;
+1E038;MODIFIER LETTER CYRILLIC SMALL I;Lm;0;L;<super> 0438;;;;N;;;;;
+1E039;MODIFIER LETTER CYRILLIC SMALL KA;Lm;0;L;<super> 043A;;;;N;;;;;
+1E03A;MODIFIER LETTER CYRILLIC SMALL EL;Lm;0;L;<super> 043B;;;;N;;;;;
+1E03B;MODIFIER LETTER CYRILLIC SMALL EM;Lm;0;L;<super> 043C;;;;N;;;;;
+1E03C;MODIFIER LETTER CYRILLIC SMALL O;Lm;0;L;<super> 043E;;;;N;;;;;
+1E03D;MODIFIER LETTER CYRILLIC SMALL PE;Lm;0;L;<super> 043F;;;;N;;;;;
+1E03E;MODIFIER LETTER CYRILLIC SMALL ER;Lm;0;L;<super> 0440;;;;N;;;;;
+1E03F;MODIFIER LETTER CYRILLIC SMALL ES;Lm;0;L;<super> 0441;;;;N;;;;;
+1E040;MODIFIER LETTER CYRILLIC SMALL TE;Lm;0;L;<super> 0442;;;;N;;;;;
+1E041;MODIFIER LETTER CYRILLIC SMALL U;Lm;0;L;<super> 0443;;;;N;;;;;
+1E042;MODIFIER LETTER CYRILLIC SMALL EF;Lm;0;L;<super> 0444;;;;N;;;;;
+1E043;MODIFIER LETTER CYRILLIC SMALL HA;Lm;0;L;<super> 0445;;;;N;;;;;
+1E044;MODIFIER LETTER CYRILLIC SMALL TSE;Lm;0;L;<super> 0446;;;;N;;;;;
+1E045;MODIFIER LETTER CYRILLIC SMALL CHE;Lm;0;L;<super> 0447;;;;N;;;;;
+1E046;MODIFIER LETTER CYRILLIC SMALL SHA;Lm;0;L;<super> 0448;;;;N;;;;;
+1E047;MODIFIER LETTER CYRILLIC SMALL YERU;Lm;0;L;<super> 044B;;;;N;;;;;
+1E048;MODIFIER LETTER CYRILLIC SMALL E;Lm;0;L;<super> 044D;;;;N;;;;;
+1E049;MODIFIER LETTER CYRILLIC SMALL YU;Lm;0;L;<super> 044E;;;;N;;;;;
+1E04A;MODIFIER LETTER CYRILLIC SMALL DZZE;Lm;0;L;<super> A689;;;;N;;;;;
+1E04B;MODIFIER LETTER CYRILLIC SMALL SCHWA;Lm;0;L;<super> 04D9;;;;N;;;;;
+1E04C;MODIFIER LETTER CYRILLIC SMALL BYELORUSSIAN-UKRAINIAN I;Lm;0;L;<super> 0456;;;;N;;;;;
+1E04D;MODIFIER LETTER CYRILLIC SMALL JE;Lm;0;L;<super> 0458;;;;N;;;;;
+1E04E;MODIFIER LETTER CYRILLIC SMALL BARRED O;Lm;0;L;<super> 04E9;;;;N;;;;;
+1E04F;MODIFIER LETTER CYRILLIC SMALL STRAIGHT U;Lm;0;L;<super> 04AF;;;;N;;;;;
+1E050;MODIFIER LETTER CYRILLIC SMALL PALOCHKA;Lm;0;L;<super> 04CF;;;;N;;;;;
+1E051;CYRILLIC SUBSCRIPT SMALL LETTER A;Lm;0;L;<sub> 0430;;;;N;;;;;
+1E052;CYRILLIC SUBSCRIPT SMALL LETTER BE;Lm;0;L;<sub> 0431;;;;N;;;;;
+1E053;CYRILLIC SUBSCRIPT SMALL LETTER VE;Lm;0;L;<sub> 0432;;;;N;;;;;
+1E054;CYRILLIC SUBSCRIPT SMALL LETTER GHE;Lm;0;L;<sub> 0433;;;;N;;;;;
+1E055;CYRILLIC SUBSCRIPT SMALL LETTER DE;Lm;0;L;<sub> 0434;;;;N;;;;;
+1E056;CYRILLIC SUBSCRIPT SMALL LETTER IE;Lm;0;L;<sub> 0435;;;;N;;;;;
+1E057;CYRILLIC SUBSCRIPT SMALL LETTER ZHE;Lm;0;L;<sub> 0436;;;;N;;;;;
+1E058;CYRILLIC SUBSCRIPT SMALL LETTER ZE;Lm;0;L;<sub> 0437;;;;N;;;;;
+1E059;CYRILLIC SUBSCRIPT SMALL LETTER I;Lm;0;L;<sub> 0438;;;;N;;;;;
+1E05A;CYRILLIC SUBSCRIPT SMALL LETTER KA;Lm;0;L;<sub> 043A;;;;N;;;;;
+1E05B;CYRILLIC SUBSCRIPT SMALL LETTER EL;Lm;0;L;<sub> 043B;;;;N;;;;;
+1E05C;CYRILLIC SUBSCRIPT SMALL LETTER O;Lm;0;L;<sub> 043E;;;;N;;;;;
+1E05D;CYRILLIC SUBSCRIPT SMALL LETTER PE;Lm;0;L;<sub> 043F;;;;N;;;;;
+1E05E;CYRILLIC SUBSCRIPT SMALL LETTER ES;Lm;0;L;<sub> 0441;;;;N;;;;;
+1E05F;CYRILLIC SUBSCRIPT SMALL LETTER U;Lm;0;L;<sub> 0443;;;;N;;;;;
+1E060;CYRILLIC SUBSCRIPT SMALL LETTER EF;Lm;0;L;<sub> 0444;;;;N;;;;;
+1E061;CYRILLIC SUBSCRIPT SMALL LETTER HA;Lm;0;L;<sub> 0445;;;;N;;;;;
+1E062;CYRILLIC SUBSCRIPT SMALL LETTER TSE;Lm;0;L;<sub> 0446;;;;N;;;;;
+1E063;CYRILLIC SUBSCRIPT SMALL LETTER CHE;Lm;0;L;<sub> 0447;;;;N;;;;;
+1E064;CYRILLIC SUBSCRIPT SMALL LETTER SHA;Lm;0;L;<sub> 0448;;;;N;;;;;
+1E065;CYRILLIC SUBSCRIPT SMALL LETTER HARD SIGN;Lm;0;L;<sub> 044A;;;;N;;;;;
+1E066;CYRILLIC SUBSCRIPT SMALL LETTER YERU;Lm;0;L;<sub> 044B;;;;N;;;;;
+1E067;CYRILLIC SUBSCRIPT SMALL LETTER GHE WITH UPTURN;Lm;0;L;<sub> 0491;;;;N;;;;;
+1E068;CYRILLIC SUBSCRIPT SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Lm;0;L;<sub> 0456;;;;N;;;;;
+1E069;CYRILLIC SUBSCRIPT SMALL LETTER DZE;Lm;0;L;<sub> 0455;;;;N;;;;;
+1E06A;CYRILLIC SUBSCRIPT SMALL LETTER DZHE;Lm;0;L;<sub> 045F;;;;N;;;;;
+1E06B;MODIFIER LETTER CYRILLIC SMALL ES WITH DESCENDER;Lm;0;L;<super> 04AB;;;;N;;;;;
+1E06C;MODIFIER LETTER CYRILLIC SMALL YERU WITH BACK YER;Lm;0;L;<super> A651;;;;N;;;;;
+1E06D;MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE;Lm;0;L;<super> 04B1;;;;N;;;;;
+1E08F;COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Mn;230;NSM;;;;;N;;;;;
1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;;
1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;;
1E102;NYIAKENG PUACHUE HMONG LETTER NTA;Lo;0;L;;;;;N;;;;;
@@ -30603,6 +30828,48 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;;
+1E4D0;NAG MUNDARI LETTER O;Lo;0;L;;;;;N;;;;;
+1E4D1;NAG MUNDARI LETTER OP;Lo;0;L;;;;;N;;;;;
+1E4D2;NAG MUNDARI LETTER OL;Lo;0;L;;;;;N;;;;;
+1E4D3;NAG MUNDARI LETTER OY;Lo;0;L;;;;;N;;;;;
+1E4D4;NAG MUNDARI LETTER ONG;Lo;0;L;;;;;N;;;;;
+1E4D5;NAG MUNDARI LETTER A;Lo;0;L;;;;;N;;;;;
+1E4D6;NAG MUNDARI LETTER AJ;Lo;0;L;;;;;N;;;;;
+1E4D7;NAG MUNDARI LETTER AB;Lo;0;L;;;;;N;;;;;
+1E4D8;NAG MUNDARI LETTER ANY;Lo;0;L;;;;;N;;;;;
+1E4D9;NAG MUNDARI LETTER AH;Lo;0;L;;;;;N;;;;;
+1E4DA;NAG MUNDARI LETTER I;Lo;0;L;;;;;N;;;;;
+1E4DB;NAG MUNDARI LETTER IS;Lo;0;L;;;;;N;;;;;
+1E4DC;NAG MUNDARI LETTER IDD;Lo;0;L;;;;;N;;;;;
+1E4DD;NAG MUNDARI LETTER IT;Lo;0;L;;;;;N;;;;;
+1E4DE;NAG MUNDARI LETTER IH;Lo;0;L;;;;;N;;;;;
+1E4DF;NAG MUNDARI LETTER U;Lo;0;L;;;;;N;;;;;
+1E4E0;NAG MUNDARI LETTER UC;Lo;0;L;;;;;N;;;;;
+1E4E1;NAG MUNDARI LETTER UD;Lo;0;L;;;;;N;;;;;
+1E4E2;NAG MUNDARI LETTER UK;Lo;0;L;;;;;N;;;;;
+1E4E3;NAG MUNDARI LETTER UR;Lo;0;L;;;;;N;;;;;
+1E4E4;NAG MUNDARI LETTER E;Lo;0;L;;;;;N;;;;;
+1E4E5;NAG MUNDARI LETTER ENN;Lo;0;L;;;;;N;;;;;
+1E4E6;NAG MUNDARI LETTER EG;Lo;0;L;;;;;N;;;;;
+1E4E7;NAG MUNDARI LETTER EM;Lo;0;L;;;;;N;;;;;
+1E4E8;NAG MUNDARI LETTER EN;Lo;0;L;;;;;N;;;;;
+1E4E9;NAG MUNDARI LETTER ETT;Lo;0;L;;;;;N;;;;;
+1E4EA;NAG MUNDARI LETTER ELL;Lo;0;L;;;;;N;;;;;
+1E4EB;NAG MUNDARI SIGN OJOD;Lm;0;L;;;;;N;;;;;
+1E4EC;NAG MUNDARI SIGN MUHOR;Mn;232;NSM;;;;;N;;;;;
+1E4ED;NAG MUNDARI SIGN TOYOR;Mn;232;NSM;;;;;N;;;;;
+1E4EE;NAG MUNDARI SIGN IKIR;Mn;220;NSM;;;;;N;;;;;
+1E4EF;NAG MUNDARI SIGN SUTUH;Mn;230;NSM;;;;;N;;;;;
+1E4F0;NAG MUNDARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
+1E4F1;NAG MUNDARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
+1E4F2;NAG MUNDARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
+1E4F3;NAG MUNDARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
+1E4F4;NAG MUNDARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
+1E4F5;NAG MUNDARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
+1E4F6;NAG MUNDARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
+1E4F7;NAG MUNDARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
+1E4F8;NAG MUNDARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
+1E4F9;NAG MUNDARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
1E7E0;ETHIOPIC SYLLABLE HHYA;Lo;0;L;;;;;N;;;;;
1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;;
1E7E2;ETHIOPIC SYLLABLE HHYI;Lo;0;L;;;;;N;;;;;
@@ -32678,6 +32945,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;;
1F6D6;HUT;So;0;ON;;;;;N;;;;;
1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;;
+1F6DC;WIRELESS;So;0;ON;;;;;N;;;;;
1F6DD;PLAYGROUND SLIDE;So;0;ON;;;;;N;;;;;
1F6DE;WHEEL;So;0;ON;;;;;N;;;;;
1F6DF;RING BUOY;So;0;ON;;;;;N;;;;;
@@ -32823,6 +33091,14 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;;
1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;;
1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;So;0;ON;;;;;N;;;;;
+1F774;LOT OF FORTUNE;So;0;ON;;;;;N;;;;;
+1F775;OCCULTATION;So;0;ON;;;;;N;;;;;
+1F776;LUNAR ECLIPSE;So;0;ON;;;;;N;;;;;
+1F77B;HAUMEA;So;0;ON;;;;;N;;;;;
+1F77C;MAKEMAKE;So;0;ON;;;;;N;;;;;
+1F77D;GONGGONG;So;0;ON;;;;;N;;;;;
+1F77E;QUAOAR;So;0;ON;;;;;N;;;;;
+1F77F;ORCUS;So;0;ON;;;;;N;;;;;
1F780;BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
1F781;BLACK UP-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
1F782;BLACK RIGHT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
@@ -32912,6 +33188,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;;
1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;;
1F7D8;NEGATIVE CIRCLED SQUARE;So;0;ON;;;;;N;;;;;
+1F7D9;NINE POINTED WHITE STAR;So;0;ON;;;;;N;;;;;
1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;;
1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;;
1F7E2;LARGE GREEN CIRCLE;So;0;ON;;;;;N;;;;;
@@ -33434,6 +33711,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FA72;BRIEFS;So;0;ON;;;;;N;;;;;
1FA73;SHORTS;So;0;ON;;;;;N;;;;;
1FA74;THONG SANDAL;So;0;ON;;;;;N;;;;;
+1FA75;LIGHT BLUE HEART;So;0;ON;;;;;N;;;;;
+1FA76;GREY HEART;So;0;ON;;;;;N;;;;;
+1FA77;PINK HEART;So;0;ON;;;;;N;;;;;
1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;;
1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;;
1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;;
@@ -33446,6 +33726,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FA84;MAGIC WAND;So;0;ON;;;;;N;;;;;
1FA85;PINATA;So;0;ON;;;;;N;;;;;
1FA86;NESTING DOLLS;So;0;ON;;;;;N;;;;;
+1FA87;MARACAS;So;0;ON;;;;;N;;;;;
+1FA88;FLUTE;So;0;ON;;;;;N;;;;;
1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;;
1FA91;CHAIR;So;0;ON;;;;;N;;;;;
1FA92;RAZOR;So;0;ON;;;;;N;;;;;
@@ -33475,6 +33757,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAAA;IDENTIFICATION CARD;So;0;ON;;;;;N;;;;;
1FAAB;LOW BATTERY;So;0;ON;;;;;N;;;;;
1FAAC;HAMSA;So;0;ON;;;;;N;;;;;
+1FAAD;FOLDING HAND FAN;So;0;ON;;;;;N;;;;;
+1FAAE;HAIR PICK;So;0;ON;;;;;N;;;;;
+1FAAF;KHANDA;So;0;ON;;;;;N;;;;;
1FAB0;FLY;So;0;ON;;;;;N;;;;;
1FAB1;WORM;So;0;ON;;;;;N;;;;;
1FAB2;BEETLE;So;0;ON;;;;;N;;;;;
@@ -33486,12 +33771,18 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAB8;CORAL;So;0;ON;;;;;N;;;;;
1FAB9;EMPTY NEST;So;0;ON;;;;;N;;;;;
1FABA;NEST WITH EGGS;So;0;ON;;;;;N;;;;;
+1FABB;HYACINTH;So;0;ON;;;;;N;;;;;
+1FABC;JELLYFISH;So;0;ON;;;;;N;;;;;
+1FABD;WING;So;0;ON;;;;;N;;;;;
+1FABF;GOOSE;So;0;ON;;;;;N;;;;;
1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;;
1FAC1;LUNGS;So;0;ON;;;;;N;;;;;
1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;;
1FAC3;PREGNANT MAN;So;0;ON;;;;;N;;;;;
1FAC4;PREGNANT PERSON;So;0;ON;;;;;N;;;;;
1FAC5;PERSON WITH CROWN;So;0;ON;;;;;N;;;;;
+1FACE;MOOSE;So;0;ON;;;;;N;;;;;
+1FACF;DONKEY;So;0;ON;;;;;N;;;;;
1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;;
1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;;
1FAD2;OLIVE;So;0;ON;;;;;N;;;;;
@@ -33502,6 +33793,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAD7;POURING LIQUID;So;0;ON;;;;;N;;;;;
1FAD8;BEANS;So;0;ON;;;;;N;;;;;
1FAD9;JAR;So;0;ON;;;;;N;;;;;
+1FADA;GINGER ROOT;So;0;ON;;;;;N;;;;;
+1FADB;PEA POD;So;0;ON;;;;;N;;;;;
1FAE0;MELTING FACE;So;0;ON;;;;;N;;;;;
1FAE1;SALUTING FACE;So;0;ON;;;;;N;;;;;
1FAE2;FACE WITH OPEN EYES AND HAND OVER MOUTH;So;0;ON;;;;;N;;;;;
@@ -33510,6 +33803,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAE5;DOTTED LINE FACE;So;0;ON;;;;;N;;;;;
1FAE6;BITING LIP;So;0;ON;;;;;N;;;;;
1FAE7;BUBBLES;So;0;ON;;;;;N;;;;;
+1FAE8;SHAKING FACE;So;0;ON;;;;;N;;;;;
1FAF0;HAND WITH INDEX FINGER AND THUMB CROSSED;So;0;ON;;;;;N;;;;;
1FAF1;RIGHTWARDS HAND;So;0;ON;;;;;N;;;;;
1FAF2;LEFTWARDS HAND;So;0;ON;;;;;N;;;;;
@@ -33517,6 +33811,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
1FAF4;PALM UP HAND;So;0;ON;;;;;N;;;;;
1FAF5;INDEX POINTING AT THE VIEWER;So;0;ON;;;;;N;;;;;
1FAF6;HEART HANDS;So;0;ON;;;;;N;;;;;
+1FAF7;LEFTWARDS PUSHING HAND;So;0;ON;;;;;N;;;;;
+1FAF8;RIGHTWARDS PUSHING HAND;So;0;ON;;;;;N;;;;;
1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;;
1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;;
1FB02;BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;;
@@ -33732,7 +34028,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
2A6DF;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;
-2B738;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
+2B739;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;
2B740;<CJK Ideograph Extension D, First>;Lo;0;L;;;;;N;;;;;
2B81D;<CJK Ideograph Extension D, Last>;Lo;0;L;;;;;N;;;;;
2B820;<CJK Ideograph Extension E, First>;Lo;0;L;;;;;N;;;;;
@@ -34283,6 +34579,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;
30000;<CJK Ideograph Extension G, First>;Lo;0;L;;;;;N;;;;;
3134A;<CJK Ideograph Extension G, Last>;Lo;0;L;;;;;N;;;;;
+31350;<CJK Ideograph Extension H, First>;Lo;0;L;;;;;N;;;;;
+323AF;<CJK Ideograph Extension H, Last>;Lo;0;L;;;;;N;;;;;
E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;
E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;
E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;;
diff --git a/admin/unidata/blocks.awk b/admin/unidata/blocks.awk
index 1c571feff38..48a14ec3ca9 100755
--- a/admin/unidata/blocks.awk
+++ b/admin/unidata/blocks.awk
@@ -23,7 +23,7 @@
### Commentary:
## This script takes as input Unicode's Blocks.txt
-## (http://www.unicode.org/Public/UNIDATA/Blocks.txt)
+## (https://www.unicode.org/Public/UNIDATA/Blocks.txt)
## and produces output for Emacs's lisp/international/charscript.el.
## It lumps together all the blocks belonging to the same language.
diff --git a/admin/unidata/confusables.txt b/admin/unidata/confusables.txt
index c75f78ec3e9..24b61d519af 100644
--- a/admin/unidata/confusables.txt
+++ b/admin/unidata/confusables.txt
@@ -1,13 +1,13 @@
-# confusables.txt
-# Date: 2021-05-29, 22:09:29 GMT
-# © 2021 Unicode®, Inc.
+# confusables.txt
+# Date: 2022-08-26, 16:49:08 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Security Mechanisms for UTS #39
-# Version: 14.0.0
+# Version: 15.0.0
#
-# For documentation and usage, see http://www.unicode.org/reports/tr39
+# For documentation and usage, see https://www.unicode.org/reports/tr39
#
05AD ; 0596 ; MA # ( ֭ → ֖ ) HEBREW ACCENT DEHI → HEBREW ACCENT TIPEHA #
@@ -2761,11 +2761,11 @@ FE87 ; 006C 0655 ; MA # ( ‎ﺇ‎ → lٕ ) ARABIC LETTER ALEF WITH HAMZA BELO
02AB ; 006C 007A ; MA # ( ʫ → lz ) LATIN SMALL LETTER LZ DIGRAPH → LATIN SMALL LETTER L, LATIN SMALL LETTER Z #
+0675 ; 006C 0674 ; MA # ( ‎ٵ‎ → ‎lٴ‎ ) ARABIC LETTER HIGH HAMZA ALEF → LATIN SMALL LETTER L, ARABIC LETTER HIGH HAMZA # →‎اٴ‎→
0623 ; 006C 0674 ; MA # ( ‎أ‎ → ‎lٴ‎ ) ARABIC LETTER ALEF WITH HAMZA ABOVE → LATIN SMALL LETTER L, ARABIC LETTER HIGH HAMZA # →‎ٵ‎→→‎اٴ‎→
FE84 ; 006C 0674 ; MA # ( ‎ﺄ‎ → ‎lٴ‎ ) ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM → LATIN SMALL LETTER L, ARABIC LETTER HIGH HAMZA # →‎أ‎→→‎ٵ‎→→‎اٴ‎→
FE83 ; 006C 0674 ; MA # ( ‎ﺃ‎ → ‎lٴ‎ ) ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM → LATIN SMALL LETTER L, ARABIC LETTER HIGH HAMZA # →‎ٵ‎→→‎اٴ‎→
0672 ; 006C 0674 ; MA # ( ‎ٲ‎ → ‎lٴ‎ ) ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE → LATIN SMALL LETTER L, ARABIC LETTER HIGH HAMZA # →‎أ‎→→‎ٵ‎→→‎اٴ‎→
-0675 ; 006C 0674 ; MA # ( ‎ٵ‎ → ‎lٴ‎ ) ARABIC LETTER HIGH HAMZA ALEF → LATIN SMALL LETTER L, ARABIC LETTER HIGH HAMZA # →‎اٴ‎→
FDF3 ; 006C 0643 0628 0631 ; MA # ( ‎ﷳ‎ → ‎lكبر‎ ) ARABIC LIGATURE AKBAR ISOLATED FORM → LATIN SMALL LETTER L, ARABIC LETTER KAF, ARABIC LETTER BEH, ARABIC LETTER REH # →‎اكبر‎→
@@ -5351,10 +5351,10 @@ FBE2 ; 0648 0302 ; MA # ( ‎ﯢ‎ → ‎و̂‎ ) ARABIC LETTER KIRGHIZ YU IS
FBDC ; 0648 0670 ; MA # ( ‎ﯜ‎ → ‎وٰ‎ ) ARABIC LETTER YU FINAL FORM → ARABIC LETTER WAW, ARABIC LETTER SUPERSCRIPT ALEF # →‎ۈ‎→
FBDB ; 0648 0670 ; MA # ( ‎ﯛ‎ → ‎وٰ‎ ) ARABIC LETTER YU ISOLATED FORM → ARABIC LETTER WAW, ARABIC LETTER SUPERSCRIPT ALEF # →‎ۈ‎→
+0676 ; 0648 0674 ; MA # ( ‎ٶ‎ → ‎وٴ‎ ) ARABIC LETTER HIGH HAMZA WAW → ARABIC LETTER WAW, ARABIC LETTER HIGH HAMZA #
0624 ; 0648 0674 ; MA # ( ‎ؤ‎ → ‎وٴ‎ ) ARABIC LETTER WAW WITH HAMZA ABOVE → ARABIC LETTER WAW, ARABIC LETTER HIGH HAMZA # →‎ٶ‎→
FE86 ; 0648 0674 ; MA # ( ‎ﺆ‎ → ‎وٴ‎ ) ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM → ARABIC LETTER WAW, ARABIC LETTER HIGH HAMZA # →‎ٶ‎→
FE85 ; 0648 0674 ; MA # ( ‎ﺅ‎ → ‎وٴ‎ ) ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM → ARABIC LETTER WAW, ARABIC LETTER HIGH HAMZA # →‎ٶ‎→
-0676 ; 0648 0674 ; MA # ( ‎ٶ‎ → ‎وٴ‎ ) ARABIC LETTER HIGH HAMZA WAW → ARABIC LETTER WAW, ARABIC LETTER HIGH HAMZA #
0677 ; 0648 0313 0674 ; MA # ( ‎ٷ‎ → ‎و̓ٴ‎ ) ARABIC LETTER U WITH HAMZA ABOVE → ARABIC LETTER WAW, COMBINING COMMA ABOVE, ARABIC LETTER HIGH HAMZA # →‎ۇٴ‎→
FBDD ; 0648 0313 0674 ; MA # ( ‎ﯝ‎ → ‎و̓ٴ‎ ) ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM → ARABIC LETTER WAW, COMBINING COMMA ABOVE, ARABIC LETTER HIGH HAMZA # →‎ۇٴ‎→
@@ -5446,12 +5446,12 @@ FCF1 ; 0649 006F ; MA # ( ‎ﳱ‎ → ‎ىo‎ ) ARABIC LIGATURE YEH WITH HEH
FCE6 ; 0649 06DB 006F ; MA # ( ‎ﳦ‎ → ‎ىۛo‎ ) ARABIC LIGATURE THEH WITH HEH MEDIAL FORM → ARABIC LETTER ALEF MAKSURA, ARABIC SMALL HIGH THREE DOTS, LATIN SMALL LETTER O # →‎ثه‎→
+0678 ; 0649 0674 ; MA # ( ‎ٸ‎ → ‎ىٴ‎ ) ARABIC LETTER HIGH HAMZA YEH → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA # →‎يٴ‎→
0626 ; 0649 0674 ; MA # ( ‎ئ‎ → ‎ىٴ‎ ) ARABIC LETTER YEH WITH HAMZA ABOVE → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA # →‎ٸ‎→→‎يٴ‎→
FE8B ; 0649 0674 ; MA # ( ‎ﺋ‎ → ‎ىٴ‎ ) ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA # →‎ئ‎→→‎ٸ‎→→‎يٴ‎→
FE8C ; 0649 0674 ; MA # ( ‎ﺌ‎ → ‎ىٴ‎ ) ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA # →‎ئ‎→→‎ٸ‎→→‎يٴ‎→
FE8A ; 0649 0674 ; MA # ( ‎ﺊ‎ → ‎ىٴ‎ ) ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA # →‎ئ‎→→‎ٸ‎→→‎يٴ‎→
FE89 ; 0649 0674 ; MA # ( ‎ﺉ‎ → ‎ىٴ‎ ) ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA # →‎ٸ‎→→‎يٴ‎→
-0678 ; 0649 0674 ; MA # ( ‎ٸ‎ → ‎ىٴ‎ ) ARABIC LETTER HIGH HAMZA YEH → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA # →‎يٴ‎→
FBEB ; 0649 0674 006C ; MA # ( ‎ﯫ‎ → ‎ىٴl‎ ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA, LATIN SMALL LETTER L # →‎ئا‎→
FBEA ; 0649 0674 006C ; MA # ( ‎ﯪ‎ → ‎ىٴl‎ ) ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM → ARABIC LETTER ALEF MAKSURA, ARABIC LETTER HIGH HAMZA, LATIN SMALL LETTER L # →‎ئا‎→
@@ -7535,10 +7535,10 @@ FA7E ; 5944 ; MA # ( 奄 → 奄 ) CJK COMPATIBILITY IDEOGRAPH-FA7E → CJK UNIF
F90C ; 5948 ; MA # ( 奈 → 奈 ) CJK COMPATIBILITY IDEOGRAPH-F90C → CJK UNIFIED IDEOGRAPH-5948 #
-F909 ; 5951 ; MA # ( 契 → 契 ) CJK COMPATIBILITY IDEOGRAPH-F909 → CJK UNIFIED IDEOGRAPH-5951 #
-
FA7F ; 5954 ; MA # ( 奔 → 奔 ) CJK COMPATIBILITY IDEOGRAPH-FA7F → CJK UNIFIED IDEOGRAPH-5954 #
+F909 ; 5951 ; MA # ( 契 → 契 ) CJK COMPATIBILITY IDEOGRAPH-F909 → CJK UNIFIED IDEOGRAPH-5951 #
+
2F85F ; 5962 ; MA # ( 奢 → 奢 ) CJK COMPATIBILITY IDEOGRAPH-2F85F → CJK UNIFIED IDEOGRAPH-5962 #
F981 ; 5973 ; MA # ( 女 → 女 ) CJK COMPATIBILITY IDEOGRAPH-F981 → CJK UNIFIED IDEOGRAPH-5973 #
diff --git a/admin/unidata/copyright.html b/admin/unidata/copyright.html
index 66e54b06fc4..567c54e72ac 100644
--- a/admin/unidata/copyright.html
+++ b/admin/unidata/copyright.html
@@ -13,7 +13,7 @@
<title>Unicode Terms of Use</title>
<link rel="stylesheet" type="text/css"
-href="http://www.unicode.org/webscripts/standard_styles.css">
+href="https://www.unicode.org/webscripts/standard_styles.css">
<style type="text/css">
pre {
@@ -32,8 +32,8 @@ pre {
<td colspan="2">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
- <td class="icon" style="width:38px; height:35px"><a href="http://www.unicode.org/"><img border="0"
- src="http://www.unicode.org/webscripts/logo60s2.gif" align="middle" alt="[Unicode]" width="34" height="33"></a></td>
+ <td class="icon" style="width:38px; height:35px"><a href="https://www.unicode.org/"><img border="0"
+ src="https://www.unicode.org/webscripts/logo60s2.gif" align="middle" alt="[Unicode]" width="34" height="33"></a></td>
<td class="icon" style="vertical-align:middle;"> &nbsp;<a class="bar"
href="https://www.unicode.org/copyright.html"><font size="3">Terms of Use</font></a></td>
<td class="bar"><a href="https://www.unicode.org/main.html" class="bar">Tech Site</a>
@@ -82,7 +82,7 @@ pre {
</tr>
<tr>
<td valign="top" class="navColCell">
- <a href="https://www.unicode.org/license.html">Unicode Data Files and Software License</a></td>
+ <a href="https://www.unicode.org/license.txt">Unicode Data Files and Software License</a></td>
</tr>
<tr>
<td class="navColTitle">Related Links</td>
@@ -112,13 +112,13 @@ pre {
<p>For the general privacy policy governing access to this site, see
the&nbsp;
- <a href="http://www.unicode.org/policies/privacy_policy.html">
+ <a href="https://www.unicode.org/policies/privacy_policy.html">
Unicode Privacy Policy</a>.</p>
<ol type="A">
<li><u><a name="1"></a>Unicode Copyright</u>
<ol>
- <li>Copyright © 1991-2021 Unicode, Inc. All rights reserved.</li>
+ <li>Copyright © 1991-2022 Unicode, Inc. All rights reserved.</li>
</ol>
</li>
@@ -153,12 +153,12 @@ http://site.icu-project.org/download/
herein.</li>
<li>Further specifications of rights and restrictions pertaining
to the use of the Unicode DATA FILES and SOFTWARE can be found in the
- <a href="https://www.unicode.org/license.html">Unicode Data Files and Software License</a>.</li>
+ <a href="https://www.unicode.org/license.txt">Unicode Data Files and Software License</a>.</li>
<li>Each version of the Unicode Standard has further
specifications of rights and restrictions of use. For the book
editions (Unicode 5.0 and earlier), these are found on the back
of the
- <a href="http://www.unicode.org/versions/Unicode5.0.0/Title.pdf">title page</a>.</li>
+ <a href="https://www.unicode.org/versions/Unicode5.0.0/Title.pdf">title page</a>.</li>
<li>
The Unicode PDF <a href="https://www.unicode.org/charts/">online code charts</a> carry specific restrictions. Those restrictions are incorporated as the
first page of each PDF code chart.</li>
@@ -224,7 +224,7 @@ http://site.icu-project.org/download/
<li><u><a name="5"></a>Trademarks &amp; Logos</u>
<ol>
<li>The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names.</li>
-<li><a href="http://www.unicode.org/policies/logo_policy.html">The Unicode Consortium Name and Trademark Usage Policy</a> (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc.</li>
+<li><a href="https://www.unicode.org/policies/logo_policy.html">The Unicode Consortium Name and Trademark Usage Policy</a> (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc.</li>
<li>All third party trademarks referenced herein are the property of their respective owners.</li>
</ol>
</li>
@@ -270,15 +270,15 @@ http://site.icu-project.org/download/
<center>
<table cellspacing="0" cellpadding="0" border="0" id="table2">
<tr>
- <td><a href="http://www.unicode.org/copyright.html">
- <img src="http://www.unicode.org/img/hb_notice.gif"
+ <td><a href="https://www.unicode.org/copyright.html">
+ <img src="https://www.unicode.org/img/hb_notice.gif"
border="0" alt="Access to Copyright and terms of use"
width="216" height="50"></a></td>
</tr>
</table>
<script language="Javascript" type="text/javascript"
- src="http://www.unicode.org/webscripts/lastModified.js">
+ src="https://www.unicode.org/webscripts/lastModified.js">
</script>
</center>
diff --git a/admin/unidata/emoji-data.txt b/admin/unidata/emoji-data.txt
index 2e9cf75ad4d..7942fc89a35 100644
--- a/admin/unidata/emoji-data.txt
+++ b/admin/unidata/emoji-data.txt
@@ -1,13 +1,13 @@
-# emoji-data-14.0.0.txt
-# Date: 2021-08-26, 17:22:22 GMT
-# © 2021 Unicode®, Inc.
+# emoji-data.txt
+# Date: 2022-08-02, 00:26:10 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Emoji Data for UTS #51
-# Used with Emoji Version 14.0 and subsequent minor revisions (if any)
+# Used with Emoji Version 15.0 and subsequent minor revisions (if any)
#
-# For documentation and usage, see http://www.unicode.org/reports/tr51
+# For documentation and usage, see https://www.unicode.org/reports/tr51
#
# Format:
# <codepoint(s)> ; <property> # <comments>
@@ -20,7 +20,6 @@
# ================================================
# All omitted code points have Emoji=No
-# @missing: 0000..10FFFF ; Emoji ; No
0023 ; Emoji # E0.0 [1] (#️) hash sign
002A ; Emoji # E0.0 [1] (*️) asterisk
@@ -341,6 +340,7 @@
1F6D1..1F6D2 ; Emoji # E3.0 [2] (🛑..🛒) stop sign..shopping cart
1F6D5 ; Emoji # E12.0 [1] (🛕) hindu temple
1F6D6..1F6D7 ; Emoji # E13.0 [2] (🛖..🛗) hut..elevator
+1F6DC ; Emoji # E15.0 [1] (🛜) wireless
1F6DD..1F6DF ; Emoji # E14.0 [3] (🛝..🛟) playground slide..ring buoy
1F6E0..1F6E5 ; Emoji # E0.7 [6] (🛠️..🛥️) hammer and wrench..motor boat
1F6E9 ; Emoji # E0.7 [1] (🛩️) small airplane
@@ -401,28 +401,36 @@
1F9E7..1F9FF ; Emoji # E11.0 [25] (🧧..🧿) red envelope..nazar amulet
1FA70..1FA73 ; Emoji # E12.0 [4] (🩰..🩳) ballet shoes..shorts
1FA74 ; Emoji # E13.0 [1] (🩴) thong sandal
+1FA75..1FA77 ; Emoji # E15.0 [3] (🩵..🩷) light blue heart..pink heart
1FA78..1FA7A ; Emoji # E12.0 [3] (🩸..🩺) drop of blood..stethoscope
1FA7B..1FA7C ; Emoji # E14.0 [2] (🩻..🩼) x-ray..crutch
1FA80..1FA82 ; Emoji # E12.0 [3] (🪀..🪂) yo-yo..parachute
1FA83..1FA86 ; Emoji # E13.0 [4] (🪃..🪆) boomerang..nesting dolls
+1FA87..1FA88 ; Emoji # E15.0 [2] (🪇..🪈) maracas..flute
1FA90..1FA95 ; Emoji # E12.0 [6] (🪐..🪕) ringed planet..banjo
1FA96..1FAA8 ; Emoji # E13.0 [19] (🪖..🪨) military helmet..rock
1FAA9..1FAAC ; Emoji # E14.0 [4] (🪩..🪬) mirror ball..hamsa
+1FAAD..1FAAF ; Emoji # E15.0 [3] (🪭..🪯) folding hand fan..khanda
1FAB0..1FAB6 ; Emoji # E13.0 [7] (🪰..🪶) fly..feather
1FAB7..1FABA ; Emoji # E14.0 [4] (🪷..🪺) lotus..nest with eggs
+1FABB..1FABD ; Emoji # E15.0 [3] (🪻..🪽) hyacinth..wing
+1FABF ; Emoji # E15.0 [1] (🪿) goose
1FAC0..1FAC2 ; Emoji # E13.0 [3] (🫀..🫂) anatomical heart..people hugging
1FAC3..1FAC5 ; Emoji # E14.0 [3] (🫃..🫅) pregnant man..person with crown
+1FACE..1FACF ; Emoji # E15.0 [2] (🫎..🫏) moose..donkey
1FAD0..1FAD6 ; Emoji # E13.0 [7] (🫐..🫖) blueberries..teapot
1FAD7..1FAD9 ; Emoji # E14.0 [3] (🫗..🫙) pouring liquid..jar
+1FADA..1FADB ; Emoji # E15.0 [2] (🫚..🫛) ginger root..pea pod
1FAE0..1FAE7 ; Emoji # E14.0 [8] (🫠..🫧) melting face..bubbles
+1FAE8 ; Emoji # E15.0 [1] (🫨) shaking face
1FAF0..1FAF6 ; Emoji # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
+1FAF7..1FAF8 ; Emoji # E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand
-# Total elements: 1404
+# Total elements: 1424
# ================================================
# All omitted code points have Emoji_Presentation=No
-# @missing: 0000..10FFFF ; Emoji_Presentation ; No
231A..231B ; Emoji_Presentation # E0.6 [2] (⌚..⌛) watch..hourglass done
23E9..23EC ; Emoji_Presentation # E0.6 [4] (⏩..⏬) fast-forward button..fast down button
@@ -625,6 +633,7 @@
1F6D1..1F6D2 ; Emoji_Presentation # E3.0 [2] (🛑..🛒) stop sign..shopping cart
1F6D5 ; Emoji_Presentation # E12.0 [1] (🛕) hindu temple
1F6D6..1F6D7 ; Emoji_Presentation # E13.0 [2] (🛖..🛗) hut..elevator
+1F6DC ; Emoji_Presentation # E15.0 [1] (🛜) wireless
1F6DD..1F6DF ; Emoji_Presentation # E14.0 [3] (🛝..🛟) playground slide..ring buoy
1F6EB..1F6EC ; Emoji_Presentation # E1.0 [2] (🛫..🛬) airplane departure..airplane arrival
1F6F4..1F6F6 ; Emoji_Presentation # E3.0 [3] (🛴..🛶) kick scooter..canoe
@@ -681,28 +690,36 @@
1F9E7..1F9FF ; Emoji_Presentation # E11.0 [25] (🧧..🧿) red envelope..nazar amulet
1FA70..1FA73 ; Emoji_Presentation # E12.0 [4] (🩰..🩳) ballet shoes..shorts
1FA74 ; Emoji_Presentation # E13.0 [1] (🩴) thong sandal
+1FA75..1FA77 ; Emoji_Presentation # E15.0 [3] (🩵..🩷) light blue heart..pink heart
1FA78..1FA7A ; Emoji_Presentation # E12.0 [3] (🩸..🩺) drop of blood..stethoscope
1FA7B..1FA7C ; Emoji_Presentation # E14.0 [2] (🩻..🩼) x-ray..crutch
1FA80..1FA82 ; Emoji_Presentation # E12.0 [3] (🪀..🪂) yo-yo..parachute
1FA83..1FA86 ; Emoji_Presentation # E13.0 [4] (🪃..🪆) boomerang..nesting dolls
+1FA87..1FA88 ; Emoji_Presentation # E15.0 [2] (🪇..🪈) maracas..flute
1FA90..1FA95 ; Emoji_Presentation # E12.0 [6] (🪐..🪕) ringed planet..banjo
1FA96..1FAA8 ; Emoji_Presentation # E13.0 [19] (🪖..🪨) military helmet..rock
1FAA9..1FAAC ; Emoji_Presentation # E14.0 [4] (🪩..🪬) mirror ball..hamsa
+1FAAD..1FAAF ; Emoji_Presentation # E15.0 [3] (🪭..🪯) folding hand fan..khanda
1FAB0..1FAB6 ; Emoji_Presentation # E13.0 [7] (🪰..🪶) fly..feather
1FAB7..1FABA ; Emoji_Presentation # E14.0 [4] (🪷..🪺) lotus..nest with eggs
+1FABB..1FABD ; Emoji_Presentation # E15.0 [3] (🪻..🪽) hyacinth..wing
+1FABF ; Emoji_Presentation # E15.0 [1] (🪿) goose
1FAC0..1FAC2 ; Emoji_Presentation # E13.0 [3] (🫀..🫂) anatomical heart..people hugging
1FAC3..1FAC5 ; Emoji_Presentation # E14.0 [3] (🫃..🫅) pregnant man..person with crown
+1FACE..1FACF ; Emoji_Presentation # E15.0 [2] (🫎..🫏) moose..donkey
1FAD0..1FAD6 ; Emoji_Presentation # E13.0 [7] (🫐..🫖) blueberries..teapot
1FAD7..1FAD9 ; Emoji_Presentation # E14.0 [3] (🫗..🫙) pouring liquid..jar
+1FADA..1FADB ; Emoji_Presentation # E15.0 [2] (🫚..🫛) ginger root..pea pod
1FAE0..1FAE7 ; Emoji_Presentation # E14.0 [8] (🫠..🫧) melting face..bubbles
+1FAE8 ; Emoji_Presentation # E15.0 [1] (🫨) shaking face
1FAF0..1FAF6 ; Emoji_Presentation # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
+1FAF7..1FAF8 ; Emoji_Presentation # E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand
-# Total elements: 1185
+# Total elements: 1205
# ================================================
# All omitted code points have Emoji_Modifier=No
-# @missing: 0000..10FFFF ; Emoji_Modifier ; No
1F3FB..1F3FF ; Emoji_Modifier # E1.0 [5] (🏻..🏿) light skin tone..dark skin tone
@@ -711,7 +728,6 @@
# ================================================
# All omitted code points have Emoji_Modifier_Base=No
-# @missing: 0000..10FFFF ; Emoji_Modifier_Base ; No
261D ; Emoji_Modifier_Base # E0.6 [1] (☝️) index pointing up
26F9 ; Emoji_Modifier_Base # E0.7 [1] (⛹️) person bouncing ball
@@ -762,13 +778,13 @@
1F9D1..1F9DD ; Emoji_Modifier_Base # E5.0 [13] (🧑..🧝) person..elf
1FAC3..1FAC5 ; Emoji_Modifier_Base # E14.0 [3] (🫃..🫅) pregnant man..person with crown
1FAF0..1FAF6 ; Emoji_Modifier_Base # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
+1FAF7..1FAF8 ; Emoji_Modifier_Base # E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand
-# Total elements: 132
+# Total elements: 134
# ================================================
# All omitted code points have Emoji_Component=No
-# @missing: 0000..10FFFF ; Emoji_Component ; No
0023 ; Emoji_Component # E0.0 [1] (#️) hash sign
002A ; Emoji_Component # E0.0 [1] (*️) asterisk
@@ -786,7 +802,6 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c
# ================================================
# All omitted code points have Extended_Pictographic=No
-# @missing: 0000..10FFFF ; Extended_Pictographic ; No
00A9 ; Extended_Pictographic# E0.6 [1] (©️) copyright
00AE ; Extended_Pictographic# E0.6 [1] (®️) registered
@@ -1190,7 +1205,8 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c
1F6D3..1F6D4 ; Extended_Pictographic# E0.0 [2] (🛓..🛔) STUPA..PAGODA
1F6D5 ; Extended_Pictographic# E12.0 [1] (🛕) hindu temple
1F6D6..1F6D7 ; Extended_Pictographic# E13.0 [2] (🛖..🛗) hut..elevator
-1F6D8..1F6DC ; Extended_Pictographic# E0.0 [5] (🛘..🛜) <reserved-1F6D8>..<reserved-1F6DC>
+1F6D8..1F6DB ; Extended_Pictographic# E0.0 [4] (🛘..🛛) <reserved-1F6D8>..<reserved-1F6DB>
+1F6DC ; Extended_Pictographic# E15.0 [1] (🛜) wireless
1F6DD..1F6DF ; Extended_Pictographic# E14.0 [3] (🛝..🛟) playground slide..ring buoy
1F6E0..1F6E5 ; Extended_Pictographic# E0.7 [6] (🛠️..🛥️) hammer and wrench..motor boat
1F6E6..1F6E8 ; Extended_Pictographic# E0.0 [3] (🛦..🛨) UP-POINTING MILITARY AIRPLANE..UP-POINTING SMALL AIRPLANE
@@ -1207,7 +1223,7 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c
1F6FA ; Extended_Pictographic# E12.0 [1] (🛺) auto rickshaw
1F6FB..1F6FC ; Extended_Pictographic# E13.0 [2] (🛻..🛼) pickup truck..roller skate
1F6FD..1F6FF ; Extended_Pictographic# E0.0 [3] (🛽..🛿) <reserved-1F6FD>..<reserved-1F6FF>
-1F774..1F77F ; Extended_Pictographic# E0.0 [12] (🝴..🝿) <reserved-1F774>..<reserved-1F77F>
+1F774..1F77F ; Extended_Pictographic# E0.0 [12] (🝴..🝿) LOT OF FORTUNE..ORCUS
1F7D5..1F7DF ; Extended_Pictographic# E0.0 [11] (🟕..🟟) CIRCLED TRIANGLE..<reserved-1F7DF>
1F7E0..1F7EB ; Extended_Pictographic# E12.0 [12] (🟠..🟫) orange circle..brown square
1F7EC..1F7EF ; Extended_Pictographic# E0.0 [4] (🟬..🟯) <reserved-1F7EC>..<reserved-1F7EF>
@@ -1266,30 +1282,37 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c
1FA00..1FA6F ; Extended_Pictographic# E0.0 [112] (🨀..🩯) NEUTRAL CHESS KING..<reserved-1FA6F>
1FA70..1FA73 ; Extended_Pictographic# E12.0 [4] (🩰..🩳) ballet shoes..shorts
1FA74 ; Extended_Pictographic# E13.0 [1] (🩴) thong sandal
-1FA75..1FA77 ; Extended_Pictographic# E0.0 [3] (🩵..🩷) <reserved-1FA75>..<reserved-1FA77>
+1FA75..1FA77 ; Extended_Pictographic# E15.0 [3] (🩵..🩷) light blue heart..pink heart
1FA78..1FA7A ; Extended_Pictographic# E12.0 [3] (🩸..🩺) drop of blood..stethoscope
1FA7B..1FA7C ; Extended_Pictographic# E14.0 [2] (🩻..🩼) x-ray..crutch
1FA7D..1FA7F ; Extended_Pictographic# E0.0 [3] (🩽..🩿) <reserved-1FA7D>..<reserved-1FA7F>
1FA80..1FA82 ; Extended_Pictographic# E12.0 [3] (🪀..🪂) yo-yo..parachute
1FA83..1FA86 ; Extended_Pictographic# E13.0 [4] (🪃..🪆) boomerang..nesting dolls
-1FA87..1FA8F ; Extended_Pictographic# E0.0 [9] (🪇..🪏) <reserved-1FA87>..<reserved-1FA8F>
+1FA87..1FA88 ; Extended_Pictographic# E15.0 [2] (🪇..🪈) maracas..flute
+1FA89..1FA8F ; Extended_Pictographic# E0.0 [7] (🪉..🪏) <reserved-1FA89>..<reserved-1FA8F>
1FA90..1FA95 ; Extended_Pictographic# E12.0 [6] (🪐..🪕) ringed planet..banjo
1FA96..1FAA8 ; Extended_Pictographic# E13.0 [19] (🪖..🪨) military helmet..rock
1FAA9..1FAAC ; Extended_Pictographic# E14.0 [4] (🪩..🪬) mirror ball..hamsa
-1FAAD..1FAAF ; Extended_Pictographic# E0.0 [3] (🪭..🪯) <reserved-1FAAD>..<reserved-1FAAF>
+1FAAD..1FAAF ; Extended_Pictographic# E15.0 [3] (🪭..🪯) folding hand fan..khanda
1FAB0..1FAB6 ; Extended_Pictographic# E13.0 [7] (🪰..🪶) fly..feather
1FAB7..1FABA ; Extended_Pictographic# E14.0 [4] (🪷..🪺) lotus..nest with eggs
-1FABB..1FABF ; Extended_Pictographic# E0.0 [5] (🪻..🪿) <reserved-1FABB>..<reserved-1FABF>
+1FABB..1FABD ; Extended_Pictographic# E15.0 [3] (🪻..🪽) hyacinth..wing
+1FABE ; Extended_Pictographic# E0.0 [1] (🪾) <reserved-1FABE>
+1FABF ; Extended_Pictographic# E15.0 [1] (🪿) goose
1FAC0..1FAC2 ; Extended_Pictographic# E13.0 [3] (🫀..🫂) anatomical heart..people hugging
1FAC3..1FAC5 ; Extended_Pictographic# E14.0 [3] (🫃..🫅) pregnant man..person with crown
-1FAC6..1FACF ; Extended_Pictographic# E0.0 [10] (🫆..🫏) <reserved-1FAC6>..<reserved-1FACF>
+1FAC6..1FACD ; Extended_Pictographic# E0.0 [8] (🫆..🫍) <reserved-1FAC6>..<reserved-1FACD>
+1FACE..1FACF ; Extended_Pictographic# E15.0 [2] (🫎..🫏) moose..donkey
1FAD0..1FAD6 ; Extended_Pictographic# E13.0 [7] (🫐..🫖) blueberries..teapot
1FAD7..1FAD9 ; Extended_Pictographic# E14.0 [3] (🫗..🫙) pouring liquid..jar
-1FADA..1FADF ; Extended_Pictographic# E0.0 [6] (🫚..🫟) <reserved-1FADA>..<reserved-1FADF>
+1FADA..1FADB ; Extended_Pictographic# E15.0 [2] (🫚..🫛) ginger root..pea pod
+1FADC..1FADF ; Extended_Pictographic# E0.0 [4] (🫜..🫟) <reserved-1FADC>..<reserved-1FADF>
1FAE0..1FAE7 ; Extended_Pictographic# E14.0 [8] (🫠..🫧) melting face..bubbles
-1FAE8..1FAEF ; Extended_Pictographic# E0.0 [8] (🫨..🫯) <reserved-1FAE8>..<reserved-1FAEF>
+1FAE8 ; Extended_Pictographic# E15.0 [1] (🫨) shaking face
+1FAE9..1FAEF ; Extended_Pictographic# E0.0 [7] (🫩..🫯) <reserved-1FAE9>..<reserved-1FAEF>
1FAF0..1FAF6 ; Extended_Pictographic# E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
-1FAF7..1FAFF ; Extended_Pictographic# E0.0 [9] (🫷..🫿) <reserved-1FAF7>..<reserved-1FAFF>
+1FAF7..1FAF8 ; Extended_Pictographic# E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand
+1FAF9..1FAFF ; Extended_Pictographic# E0.0 [7] (🫹..🫿) <reserved-1FAF9>..<reserved-1FAFF>
1FC00..1FFFD ; Extended_Pictographic# E0.0[1022] (🰀..🿽) <reserved-1FC00>..<reserved-1FFFD>
# Total elements: 3537
diff --git a/admin/unidata/emoji-sequences.txt b/admin/unidata/emoji-sequences.txt
index dedf7ff543b..ffd40668117 100644
--- a/admin/unidata/emoji-sequences.txt
+++ b/admin/unidata/emoji-sequences.txt
@@ -1,13 +1,13 @@
# emoji-sequences.txt
-# Date: 2021-08-26, 17:22:22 GMT
-# © 2021 Unicode®, Inc.
+# Date: 2022-08-15, 23:13:41 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Emoji Sequence Data for UTS #51
-# Version: 14.0
+# Version: 15.0
#
-# For documentation and usage, see http://www.unicode.org/reports/tr51
+# For documentation and usage, see https://www.unicode.org/reports/tr51
#
# Format:
# code_point(s) ; type_field ; description # comments
@@ -38,144 +38,145 @@
# Basic_Emoji
-231A..231B ; Basic_Emoji ; watch # E0.6 [2] (⌚..⌛)
-23E9..23EC ; Basic_Emoji ; fast-forward button # E0.6 [4] (⏩..⏬)
+
+231A..231B ; Basic_Emoji ; watch..hourglass done # E0.6 [2] (⌚..⌛)
+23E9..23EC ; Basic_Emoji ; fast-forward button..fast down button # E0.6 [4] (⏩..⏬)
23F0 ; Basic_Emoji ; alarm clock # E0.6 [1] (⏰)
23F3 ; Basic_Emoji ; hourglass not done # E0.6 [1] (⏳)
-25FD..25FE ; Basic_Emoji ; white medium-small square # E0.6 [2] (◽..◾)
-2614..2615 ; Basic_Emoji ; umbrella with rain drops # E0.6 [2] (☔..☕)
-2648..2653 ; Basic_Emoji ; Aries # E0.6 [12] (♈..♓)
+25FD..25FE ; Basic_Emoji ; white medium-small square..black medium-small square # E0.6 [2] (◽..◾)
+2614..2615 ; Basic_Emoji ; umbrella with rain drops..hot beverage # E0.6 [2] (☔..☕)
+2648..2653 ; Basic_Emoji ; Aries..Pisces # E0.6 [12] (♈..♓)
267F ; Basic_Emoji ; wheelchair symbol # E0.6 [1] (♿)
2693 ; Basic_Emoji ; anchor # E0.6 [1] (⚓)
26A1 ; Basic_Emoji ; high voltage # E0.6 [1] (⚡)
-26AA..26AB ; Basic_Emoji ; white circle # E0.6 [2] (⚪..⚫)
-26BD..26BE ; Basic_Emoji ; soccer ball # E0.6 [2] (⚽..⚾)
-26C4..26C5 ; Basic_Emoji ; snowman without snow # E0.6 [2] (⛄..⛅)
+26AA..26AB ; Basic_Emoji ; white circle..black circle # E0.6 [2] (⚪..⚫)
+26BD..26BE ; Basic_Emoji ; soccer ball..baseball # E0.6 [2] (⚽..⚾)
+26C4..26C5 ; Basic_Emoji ; snowman without snow..sun behind cloud # E0.6 [2] (⛄..⛅)
26CE ; Basic_Emoji ; Ophiuchus # E0.6 [1] (⛎)
26D4 ; Basic_Emoji ; no entry # E0.6 [1] (⛔)
26EA ; Basic_Emoji ; church # E0.6 [1] (⛪)
-26F2..26F3 ; Basic_Emoji ; fountain # E0.6 [2] (⛲..⛳)
+26F2..26F3 ; Basic_Emoji ; fountain..flag in hole # E0.6 [2] (⛲..⛳)
26F5 ; Basic_Emoji ; sailboat # E0.6 [1] (⛵)
26FA ; Basic_Emoji ; tent # E0.6 [1] (⛺)
26FD ; Basic_Emoji ; fuel pump # E0.6 [1] (⛽)
2705 ; Basic_Emoji ; check mark button # E0.6 [1] (✅)
-270A..270B ; Basic_Emoji ; raised fist # E0.6 [2] (✊..✋)
+270A..270B ; Basic_Emoji ; raised fist..raised hand # E0.6 [2] (✊..✋)
2728 ; Basic_Emoji ; sparkles # E0.6 [1] (✨)
274C ; Basic_Emoji ; cross mark # E0.6 [1] (❌)
274E ; Basic_Emoji ; cross mark button # E0.6 [1] (❎)
-2753..2755 ; Basic_Emoji ; red question mark # E0.6 [3] (❓..❕)
+2753..2755 ; Basic_Emoji ; red question mark..white exclamation mark # E0.6 [3] (❓..❕)
2757 ; Basic_Emoji ; red exclamation mark # E0.6 [1] (❗)
-2795..2797 ; Basic_Emoji ; plus # E0.6 [3] (➕..➗)
+2795..2797 ; Basic_Emoji ; plus..divide # E0.6 [3] (➕..➗)
27B0 ; Basic_Emoji ; curly loop # E0.6 [1] (➰)
27BF ; Basic_Emoji ; double curly loop # E1.0 [1] (➿)
-2B1B..2B1C ; Basic_Emoji ; black large square # E0.6 [2] (⬛..⬜)
+2B1B..2B1C ; Basic_Emoji ; black large square..white large square # E0.6 [2] (⬛..⬜)
2B50 ; Basic_Emoji ; star # E0.6 [1] (⭐)
2B55 ; Basic_Emoji ; hollow red circle # E0.6 [1] (⭕)
1F004 ; Basic_Emoji ; mahjong red dragon # E0.6 [1] (🀄)
1F0CF ; Basic_Emoji ; joker # E0.6 [1] (🃏)
1F18E ; Basic_Emoji ; AB button (blood type) # E0.6 [1] (🆎)
-1F191..1F19A ; Basic_Emoji ; CL button # E0.6 [10] (🆑..🆚)
+1F191..1F19A ; Basic_Emoji ; CL button..VS button # E0.6 [10] (🆑..🆚)
1F201 ; Basic_Emoji ; Japanese “here” button # E0.6 [1] (🈁)
1F21A ; Basic_Emoji ; Japanese “free of charge” button # E0.6 [1] (🈚)
1F22F ; Basic_Emoji ; Japanese “reserved” button # E0.6 [1] (🈯)
-1F232..1F236 ; Basic_Emoji ; Japanese “prohibited” button # E0.6 [5] (🈲..🈶)
-1F238..1F23A ; Basic_Emoji ; Japanese “application” button # E0.6 [3] (🈸..🈺)
-1F250..1F251 ; Basic_Emoji ; Japanese “bargain” button # E0.6 [2] (🉐..🉑)
-1F300..1F30C ; Basic_Emoji ; cyclone # E0.6 [13] (🌀..🌌)
-1F30D..1F30E ; Basic_Emoji ; globe showing Europe-Africa # E0.7 [2] (🌍..🌎)
+1F232..1F236 ; Basic_Emoji ; Japanese “prohibited” button..Japanese “not free of charge” button#E0.6 [5] (🈲..🈶)
+1F238..1F23A ; Basic_Emoji ; Japanese “application” button..Japanese “open for business” button#E0.6 [3] (🈸..🈺)
+1F250..1F251 ; Basic_Emoji ; Japanese “bargain” button..Japanese “acceptable” button # E0.6 [2] (🉐..🉑)
+1F300..1F30C ; Basic_Emoji ; cyclone..milky way # E0.6 [13] (🌀..🌌)
+1F30D..1F30E ; Basic_Emoji ; globe showing Europe-Africa..globe showing Americas # E0.7 [2] (🌍..🌎)
1F30F ; Basic_Emoji ; globe showing Asia-Australia # E0.6 [1] (🌏)
1F310 ; Basic_Emoji ; globe with meridians # E1.0 [1] (🌐)
1F311 ; Basic_Emoji ; new moon # E0.6 [1] (🌑)
1F312 ; Basic_Emoji ; waxing crescent moon # E1.0 [1] (🌒)
-1F313..1F315 ; Basic_Emoji ; first quarter moon # E0.6 [3] (🌓..🌕)
-1F316..1F318 ; Basic_Emoji ; waning gibbous moon # E1.0 [3] (🌖..🌘)
+1F313..1F315 ; Basic_Emoji ; first quarter moon..full moon # E0.6 [3] (🌓..🌕)
+1F316..1F318 ; Basic_Emoji ; waning gibbous moon..waning crescent moon # E1.0 [3] (🌖..🌘)
1F319 ; Basic_Emoji ; crescent moon # E0.6 [1] (🌙)
1F31A ; Basic_Emoji ; new moon face # E1.0 [1] (🌚)
1F31B ; Basic_Emoji ; first quarter moon face # E0.6 [1] (🌛)
1F31C ; Basic_Emoji ; last quarter moon face # E0.7 [1] (🌜)
-1F31D..1F31E ; Basic_Emoji ; full moon face # E1.0 [2] (🌝..🌞)
-1F31F..1F320 ; Basic_Emoji ; glowing star # E0.6 [2] (🌟..🌠)
-1F32D..1F32F ; Basic_Emoji ; hot dog # E1.0 [3] (🌭..🌯)
-1F330..1F331 ; Basic_Emoji ; chestnut # E0.6 [2] (🌰..🌱)
-1F332..1F333 ; Basic_Emoji ; evergreen tree # E1.0 [2] (🌲..🌳)
-1F334..1F335 ; Basic_Emoji ; palm tree # E0.6 [2] (🌴..🌵)
-1F337..1F34A ; Basic_Emoji ; tulip # E0.6 [20] (🌷..🍊)
+1F31D..1F31E ; Basic_Emoji ; full moon face..sun with face # E1.0 [2] (🌝..🌞)
+1F31F..1F320 ; Basic_Emoji ; glowing star..shooting star # E0.6 [2] (🌟..🌠)
+1F32D..1F32F ; Basic_Emoji ; hot dog..burrito # E1.0 [3] (🌭..🌯)
+1F330..1F331 ; Basic_Emoji ; chestnut..seedling # E0.6 [2] (🌰..🌱)
+1F332..1F333 ; Basic_Emoji ; evergreen tree..deciduous tree # E1.0 [2] (🌲..🌳)
+1F334..1F335 ; Basic_Emoji ; palm tree..cactus # E0.6 [2] (🌴..🌵)
+1F337..1F34A ; Basic_Emoji ; tulip..tangerine # E0.6 [20] (🌷..🍊)
1F34B ; Basic_Emoji ; lemon # E1.0 [1] (🍋)
-1F34C..1F34F ; Basic_Emoji ; banana # E0.6 [4] (🍌..🍏)
+1F34C..1F34F ; Basic_Emoji ; banana..green apple # E0.6 [4] (🍌..🍏)
1F350 ; Basic_Emoji ; pear # E1.0 [1] (🍐)
-1F351..1F37B ; Basic_Emoji ; peach # E0.6 [43] (🍑..🍻)
+1F351..1F37B ; Basic_Emoji ; peach..clinking beer mugs # E0.6 [43] (🍑..🍻)
1F37C ; Basic_Emoji ; baby bottle # E1.0 [1] (🍼)
-1F37E..1F37F ; Basic_Emoji ; bottle with popping cork # E1.0 [2] (🍾..🍿)
-1F380..1F393 ; Basic_Emoji ; ribbon # E0.6 [20] (🎀..🎓)
-1F3A0..1F3C4 ; Basic_Emoji ; carousel horse # E0.6 [37] (🎠..🏄)
+1F37E..1F37F ; Basic_Emoji ; bottle with popping cork..popcorn # E1.0 [2] (🍾..🍿)
+1F380..1F393 ; Basic_Emoji ; ribbon..graduation cap # E0.6 [20] (🎀..🎓)
+1F3A0..1F3C4 ; Basic_Emoji ; carousel horse..person surfing # E0.6 [37] (🎠..🏄)
1F3C5 ; Basic_Emoji ; sports medal # E1.0 [1] (🏅)
1F3C6 ; Basic_Emoji ; trophy # E0.6 [1] (🏆)
1F3C7 ; Basic_Emoji ; horse racing # E1.0 [1] (🏇)
1F3C8 ; Basic_Emoji ; american football # E0.6 [1] (🏈)
1F3C9 ; Basic_Emoji ; rugby football # E1.0 [1] (🏉)
1F3CA ; Basic_Emoji ; person swimming # E0.6 [1] (🏊)
-1F3CF..1F3D3 ; Basic_Emoji ; cricket game # E1.0 [5] (🏏..🏓)
-1F3E0..1F3E3 ; Basic_Emoji ; house # E0.6 [4] (🏠..🏣)
+1F3CF..1F3D3 ; Basic_Emoji ; cricket game..ping pong # E1.0 [5] (🏏..🏓)
+1F3E0..1F3E3 ; Basic_Emoji ; house..Japanese post office # E0.6 [4] (🏠..🏣)
1F3E4 ; Basic_Emoji ; post office # E1.0 [1] (🏤)
-1F3E5..1F3F0 ; Basic_Emoji ; hospital # E0.6 [12] (🏥..🏰)
+1F3E5..1F3F0 ; Basic_Emoji ; hospital..castle # E0.6 [12] (🏥..🏰)
1F3F4 ; Basic_Emoji ; black flag # E1.0 [1] (🏴)
-1F3F8..1F407 ; Basic_Emoji ; badminton # E1.0 [16] (🏸..🐇)
+1F3F8..1F407 ; Basic_Emoji ; badminton..rabbit # E1.0 [16] (🏸..🐇)
1F408 ; Basic_Emoji ; cat # E0.7 [1] (🐈)
-1F409..1F40B ; Basic_Emoji ; dragon # E1.0 [3] (🐉..🐋)
-1F40C..1F40E ; Basic_Emoji ; snail # E0.6 [3] (🐌..🐎)
-1F40F..1F410 ; Basic_Emoji ; ram # E1.0 [2] (🐏..🐐)
-1F411..1F412 ; Basic_Emoji ; ewe # E0.6 [2] (🐑..🐒)
+1F409..1F40B ; Basic_Emoji ; dragon..whale # E1.0 [3] (🐉..🐋)
+1F40C..1F40E ; Basic_Emoji ; snail..horse # E0.6 [3] (🐌..🐎)
+1F40F..1F410 ; Basic_Emoji ; ram..goat # E1.0 [2] (🐏..🐐)
+1F411..1F412 ; Basic_Emoji ; ewe..monkey # E0.6 [2] (🐑..🐒)
1F413 ; Basic_Emoji ; rooster # E1.0 [1] (🐓)
1F414 ; Basic_Emoji ; chicken # E0.6 [1] (🐔)
1F415 ; Basic_Emoji ; dog # E0.7 [1] (🐕)
1F416 ; Basic_Emoji ; pig # E1.0 [1] (🐖)
-1F417..1F429 ; Basic_Emoji ; boar # E0.6 [19] (🐗..🐩)
+1F417..1F429 ; Basic_Emoji ; boar..poodle # E0.6 [19] (🐗..🐩)
1F42A ; Basic_Emoji ; camel # E1.0 [1] (🐪)
-1F42B..1F43E ; Basic_Emoji ; two-hump camel # E0.6 [20] (🐫..🐾)
+1F42B..1F43E ; Basic_Emoji ; two-hump camel..paw prints # E0.6 [20] (🐫..🐾)
1F440 ; Basic_Emoji ; eyes # E0.6 [1] (👀)
-1F442..1F464 ; Basic_Emoji ; ear # E0.6 [35] (👂..👤)
+1F442..1F464 ; Basic_Emoji ; ear..bust in silhouette # E0.6 [35] (👂..👤)
1F465 ; Basic_Emoji ; busts in silhouette # E1.0 [1] (👥)
-1F466..1F46B ; Basic_Emoji ; boy # E0.6 [6] (👦..👫)
-1F46C..1F46D ; Basic_Emoji ; men holding hands # E1.0 [2] (👬..👭)
-1F46E..1F4AC ; Basic_Emoji ; police officer # E0.6 [63] (👮..💬)
+1F466..1F46B ; Basic_Emoji ; boy..woman and man holding hands # E0.6 [6] (👦..👫)
+1F46C..1F46D ; Basic_Emoji ; men holding hands..women holding hands # E1.0 [2] (👬..👭)
+1F46E..1F4AC ; Basic_Emoji ; police officer..speech balloon # E0.6 [63] (👮..💬)
1F4AD ; Basic_Emoji ; thought balloon # E1.0 [1] (💭)
-1F4AE..1F4B5 ; Basic_Emoji ; white flower # E0.6 [8] (💮..💵)
-1F4B6..1F4B7 ; Basic_Emoji ; euro banknote # E1.0 [2] (💶..💷)
-1F4B8..1F4EB ; Basic_Emoji ; money with wings # E0.6 [52] (💸..📫)
-1F4EC..1F4ED ; Basic_Emoji ; open mailbox with raised flag # E0.7 [2] (📬..📭)
+1F4AE..1F4B5 ; Basic_Emoji ; white flower..dollar banknote # E0.6 [8] (💮..💵)
+1F4B6..1F4B7 ; Basic_Emoji ; euro banknote..pound banknote # E1.0 [2] (💶..💷)
+1F4B8..1F4EB ; Basic_Emoji ; money with wings..closed mailbox with raised flag # E0.6 [52] (💸..📫)
+1F4EC..1F4ED ; Basic_Emoji ; open mailbox with raised flag..open mailbox with lowered flag # E0.7 [2] (📬..📭)
1F4EE ; Basic_Emoji ; postbox # E0.6 [1] (📮)
1F4EF ; Basic_Emoji ; postal horn # E1.0 [1] (📯)
-1F4F0..1F4F4 ; Basic_Emoji ; newspaper # E0.6 [5] (📰..📴)
+1F4F0..1F4F4 ; Basic_Emoji ; newspaper..mobile phone off # E0.6 [5] (📰..📴)
1F4F5 ; Basic_Emoji ; no mobile phones # E1.0 [1] (📵)
-1F4F6..1F4F7 ; Basic_Emoji ; antenna bars # E0.6 [2] (📶..📷)
+1F4F6..1F4F7 ; Basic_Emoji ; antenna bars..camera # E0.6 [2] (📶..📷)
1F4F8 ; Basic_Emoji ; camera with flash # E1.0 [1] (📸)
-1F4F9..1F4FC ; Basic_Emoji ; video camera # E0.6 [4] (📹..📼)
-1F4FF..1F502 ; Basic_Emoji ; prayer beads # E1.0 [4] (📿..🔂)
+1F4F9..1F4FC ; Basic_Emoji ; video camera..videocassette # E0.6 [4] (📹..📼)
+1F4FF..1F502 ; Basic_Emoji ; prayer beads..repeat single button # E1.0 [4] (📿..🔂)
1F503 ; Basic_Emoji ; clockwise vertical arrows # E0.6 [1] (🔃)
-1F504..1F507 ; Basic_Emoji ; counterclockwise arrows button # E1.0 [4] (🔄..🔇)
+1F504..1F507 ; Basic_Emoji ; counterclockwise arrows button..muted speaker # E1.0 [4] (🔄..🔇)
1F508 ; Basic_Emoji ; speaker low volume # E0.7 [1] (🔈)
1F509 ; Basic_Emoji ; speaker medium volume # E1.0 [1] (🔉)
-1F50A..1F514 ; Basic_Emoji ; speaker high volume # E0.6 [11] (🔊..🔔)
+1F50A..1F514 ; Basic_Emoji ; speaker high volume..bell # E0.6 [11] (🔊..🔔)
1F515 ; Basic_Emoji ; bell with slash # E1.0 [1] (🔕)
-1F516..1F52B ; Basic_Emoji ; bookmark # E0.6 [22] (🔖..🔫)
-1F52C..1F52D ; Basic_Emoji ; microscope # E1.0 [2] (🔬..🔭)
-1F52E..1F53D ; Basic_Emoji ; crystal ball # E0.6 [16] (🔮..🔽)
-1F54B..1F54E ; Basic_Emoji ; kaaba # E1.0 [4] (🕋..🕎)
-1F550..1F55B ; Basic_Emoji ; one o’clock # E0.6 [12] (🕐..🕛)
-1F55C..1F567 ; Basic_Emoji ; one-thirty # E0.7 [12] (🕜..🕧)
+1F516..1F52B ; Basic_Emoji ; bookmark..water pistol # E0.6 [22] (🔖..🔫)
+1F52C..1F52D ; Basic_Emoji ; microscope..telescope # E1.0 [2] (🔬..🔭)
+1F52E..1F53D ; Basic_Emoji ; crystal ball..downwards button # E0.6 [16] (🔮..🔽)
+1F54B..1F54E ; Basic_Emoji ; kaaba..menorah # E1.0 [4] (🕋..🕎)
+1F550..1F55B ; Basic_Emoji ; one o’clock..twelve o’clock # E0.6 [12] (🕐..🕛)
+1F55C..1F567 ; Basic_Emoji ; one-thirty..twelve-thirty # E0.7 [12] (🕜..🕧)
1F57A ; Basic_Emoji ; man dancing # E3.0 [1] (🕺)
-1F595..1F596 ; Basic_Emoji ; middle finger # E1.0 [2] (🖕..🖖)
+1F595..1F596 ; Basic_Emoji ; middle finger..vulcan salute # E1.0 [2] (🖕..🖖)
1F5A4 ; Basic_Emoji ; black heart # E3.0 [1] (🖤)
-1F5FB..1F5FF ; Basic_Emoji ; mount fuji # E0.6 [5] (🗻..🗿)
+1F5FB..1F5FF ; Basic_Emoji ; mount fuji..moai # E0.6 [5] (🗻..🗿)
1F600 ; Basic_Emoji ; grinning face # E1.0 [1] (😀)
-1F601..1F606 ; Basic_Emoji ; beaming face with smiling eyes # E0.6 [6] (😁..😆)
-1F607..1F608 ; Basic_Emoji ; smiling face with halo # E1.0 [2] (😇..😈)
-1F609..1F60D ; Basic_Emoji ; winking face # E0.6 [5] (😉..😍)
+1F601..1F606 ; Basic_Emoji ; beaming face with smiling eyes..grinning squinting face # E0.6 [6] (😁..😆)
+1F607..1F608 ; Basic_Emoji ; smiling face with halo..smiling face with horns # E1.0 [2] (😇..😈)
+1F609..1F60D ; Basic_Emoji ; winking face..smiling face with heart-eyes # E0.6 [5] (😉..😍)
1F60E ; Basic_Emoji ; smiling face with sunglasses # E1.0 [1] (😎)
1F60F ; Basic_Emoji ; smirking face # E0.6 [1] (😏)
1F610 ; Basic_Emoji ; neutral face # E0.7 [1] (😐)
1F611 ; Basic_Emoji ; expressionless face # E1.0 [1] (😑)
-1F612..1F614 ; Basic_Emoji ; unamused face # E0.6 [3] (😒..😔)
+1F612..1F614 ; Basic_Emoji ; unamused face..pensive face # E0.6 [3] (😒..😔)
1F615 ; Basic_Emoji ; confused face # E1.0 [1] (😕)
1F616 ; Basic_Emoji ; confounded face # E0.6 [1] (😖)
1F617 ; Basic_Emoji ; kissing face # E1.0 [1] (😗)
@@ -183,132 +184,142 @@
1F619 ; Basic_Emoji ; kissing face with smiling eyes # E1.0 [1] (😙)
1F61A ; Basic_Emoji ; kissing face with closed eyes # E0.6 [1] (😚)
1F61B ; Basic_Emoji ; face with tongue # E1.0 [1] (😛)
-1F61C..1F61E ; Basic_Emoji ; winking face with tongue # E0.6 [3] (😜..😞)
+1F61C..1F61E ; Basic_Emoji ; winking face with tongue..disappointed face # E0.6 [3] (😜..😞)
1F61F ; Basic_Emoji ; worried face # E1.0 [1] (😟)
-1F620..1F625 ; Basic_Emoji ; angry face # E0.6 [6] (😠..😥)
-1F626..1F627 ; Basic_Emoji ; frowning face with open mouth # E1.0 [2] (😦..😧)
-1F628..1F62B ; Basic_Emoji ; fearful face # E0.6 [4] (😨..😫)
+1F620..1F625 ; Basic_Emoji ; angry face..sad but relieved face # E0.6 [6] (😠..😥)
+1F626..1F627 ; Basic_Emoji ; frowning face with open mouth..anguished face # E1.0 [2] (😦..😧)
+1F628..1F62B ; Basic_Emoji ; fearful face..tired face # E0.6 [4] (😨..😫)
1F62C ; Basic_Emoji ; grimacing face # E1.0 [1] (😬)
1F62D ; Basic_Emoji ; loudly crying face # E0.6 [1] (😭)
-1F62E..1F62F ; Basic_Emoji ; face with open mouth # E1.0 [2] (😮..😯)
-1F630..1F633 ; Basic_Emoji ; anxious face with sweat # E0.6 [4] (😰..😳)
+1F62E..1F62F ; Basic_Emoji ; face with open mouth..hushed face # E1.0 [2] (😮..😯)
+1F630..1F633 ; Basic_Emoji ; anxious face with sweat..flushed face # E0.6 [4] (😰..😳)
1F634 ; Basic_Emoji ; sleeping face # E1.0 [1] (😴)
1F635 ; Basic_Emoji ; face with crossed-out eyes # E0.6 [1] (😵)
1F636 ; Basic_Emoji ; face without mouth # E1.0 [1] (😶)
-1F637..1F640 ; Basic_Emoji ; face with medical mask # E0.6 [10] (😷..🙀)
-1F641..1F644 ; Basic_Emoji ; slightly frowning face # E1.0 [4] (🙁..🙄)
-1F645..1F64F ; Basic_Emoji ; person gesturing NO # E0.6 [11] (🙅..🙏)
+1F637..1F640 ; Basic_Emoji ; face with medical mask..weary cat # E0.6 [10] (😷..🙀)
+1F641..1F644 ; Basic_Emoji ; slightly frowning face..face with rolling eyes # E1.0 [4] (🙁..🙄)
+1F645..1F64F ; Basic_Emoji ; person gesturing NO..folded hands # E0.6 [11] (🙅..🙏)
1F680 ; Basic_Emoji ; rocket # E0.6 [1] (🚀)
-1F681..1F682 ; Basic_Emoji ; helicopter # E1.0 [2] (🚁..🚂)
-1F683..1F685 ; Basic_Emoji ; railway car # E0.6 [3] (🚃..🚅)
+1F681..1F682 ; Basic_Emoji ; helicopter..locomotive # E1.0 [2] (🚁..🚂)
+1F683..1F685 ; Basic_Emoji ; railway car..bullet train # E0.6 [3] (🚃..🚅)
1F686 ; Basic_Emoji ; train # E1.0 [1] (🚆)
1F687 ; Basic_Emoji ; metro # E0.6 [1] (🚇)
1F688 ; Basic_Emoji ; light rail # E1.0 [1] (🚈)
1F689 ; Basic_Emoji ; station # E0.6 [1] (🚉)
-1F68A..1F68B ; Basic_Emoji ; tram # E1.0 [2] (🚊..🚋)
+1F68A..1F68B ; Basic_Emoji ; tram..tram car # E1.0 [2] (🚊..🚋)
1F68C ; Basic_Emoji ; bus # E0.6 [1] (🚌)
1F68D ; Basic_Emoji ; oncoming bus # E0.7 [1] (🚍)
1F68E ; Basic_Emoji ; trolleybus # E1.0 [1] (🚎)
1F68F ; Basic_Emoji ; bus stop # E0.6 [1] (🚏)
1F690 ; Basic_Emoji ; minibus # E1.0 [1] (🚐)
-1F691..1F693 ; Basic_Emoji ; ambulance # E0.6 [3] (🚑..🚓)
+1F691..1F693 ; Basic_Emoji ; ambulance..police car # E0.6 [3] (🚑..🚓)
1F694 ; Basic_Emoji ; oncoming police car # E0.7 [1] (🚔)
1F695 ; Basic_Emoji ; taxi # E0.6 [1] (🚕)
1F696 ; Basic_Emoji ; oncoming taxi # E1.0 [1] (🚖)
1F697 ; Basic_Emoji ; automobile # E0.6 [1] (🚗)
1F698 ; Basic_Emoji ; oncoming automobile # E0.7 [1] (🚘)
-1F699..1F69A ; Basic_Emoji ; sport utility vehicle # E0.6 [2] (🚙..🚚)
-1F69B..1F6A1 ; Basic_Emoji ; articulated lorry # E1.0 [7] (🚛..🚡)
+1F699..1F69A ; Basic_Emoji ; sport utility vehicle..delivery truck # E0.6 [2] (🚙..🚚)
+1F69B..1F6A1 ; Basic_Emoji ; articulated lorry..aerial tramway # E1.0 [7] (🚛..🚡)
1F6A2 ; Basic_Emoji ; ship # E0.6 [1] (🚢)
1F6A3 ; Basic_Emoji ; person rowing boat # E1.0 [1] (🚣)
-1F6A4..1F6A5 ; Basic_Emoji ; speedboat # E0.6 [2] (🚤..🚥)
+1F6A4..1F6A5 ; Basic_Emoji ; speedboat..horizontal traffic light # E0.6 [2] (🚤..🚥)
1F6A6 ; Basic_Emoji ; vertical traffic light # E1.0 [1] (🚦)
-1F6A7..1F6AD ; Basic_Emoji ; construction # E0.6 [7] (🚧..🚭)
-1F6AE..1F6B1 ; Basic_Emoji ; litter in bin sign # E1.0 [4] (🚮..🚱)
+1F6A7..1F6AD ; Basic_Emoji ; construction..no smoking # E0.6 [7] (🚧..🚭)
+1F6AE..1F6B1 ; Basic_Emoji ; litter in bin sign..non-potable water # E1.0 [4] (🚮..🚱)
1F6B2 ; Basic_Emoji ; bicycle # E0.6 [1] (🚲)
-1F6B3..1F6B5 ; Basic_Emoji ; no bicycles # E1.0 [3] (🚳..🚵)
+1F6B3..1F6B5 ; Basic_Emoji ; no bicycles..person mountain biking # E1.0 [3] (🚳..🚵)
1F6B6 ; Basic_Emoji ; person walking # E0.6 [1] (🚶)
-1F6B7..1F6B8 ; Basic_Emoji ; no pedestrians # E1.0 [2] (🚷..🚸)
-1F6B9..1F6BE ; Basic_Emoji ; men’s room # E0.6 [6] (🚹..🚾)
+1F6B7..1F6B8 ; Basic_Emoji ; no pedestrians..children crossing # E1.0 [2] (🚷..🚸)
+1F6B9..1F6BE ; Basic_Emoji ; men’s room..water closet # E0.6 [6] (🚹..🚾)
1F6BF ; Basic_Emoji ; shower # E1.0 [1] (🚿)
1F6C0 ; Basic_Emoji ; person taking bath # E0.6 [1] (🛀)
-1F6C1..1F6C5 ; Basic_Emoji ; bathtub # E1.0 [5] (🛁..🛅)
+1F6C1..1F6C5 ; Basic_Emoji ; bathtub..left luggage # E1.0 [5] (🛁..🛅)
1F6CC ; Basic_Emoji ; person in bed # E1.0 [1] (🛌)
1F6D0 ; Basic_Emoji ; place of worship # E1.0 [1] (🛐)
-1F6D1..1F6D2 ; Basic_Emoji ; stop sign # E3.0 [2] (🛑..🛒)
+1F6D1..1F6D2 ; Basic_Emoji ; stop sign..shopping cart # E3.0 [2] (🛑..🛒)
1F6D5 ; Basic_Emoji ; hindu temple # E12.0 [1] (🛕)
-1F6D6..1F6D7 ; Basic_Emoji ; hut # E13.0 [2] (🛖..🛗)
-1F6DD..1F6DF ; Basic_Emoji ; playground slide # E14.0 [3] (🛝..🛟)
-1F6EB..1F6EC ; Basic_Emoji ; airplane departure # E1.0 [2] (🛫..🛬)
-1F6F4..1F6F6 ; Basic_Emoji ; kick scooter # E3.0 [3] (🛴..🛶)
-1F6F7..1F6F8 ; Basic_Emoji ; sled # E5.0 [2] (🛷..🛸)
+1F6D6..1F6D7 ; Basic_Emoji ; hut..elevator # E13.0 [2] (🛖..🛗)
+1F6DC ; Basic_Emoji ; wireless # E15.0 [1] (🛜)
+1F6DD..1F6DF ; Basic_Emoji ; playground slide..ring buoy # E14.0 [3] (🛝..🛟)
+1F6EB..1F6EC ; Basic_Emoji ; airplane departure..airplane arrival # E1.0 [2] (🛫..🛬)
+1F6F4..1F6F6 ; Basic_Emoji ; kick scooter..canoe # E3.0 [3] (🛴..🛶)
+1F6F7..1F6F8 ; Basic_Emoji ; sled..flying saucer # E5.0 [2] (🛷..🛸)
1F6F9 ; Basic_Emoji ; skateboard # E11.0 [1] (🛹)
1F6FA ; Basic_Emoji ; auto rickshaw # E12.0 [1] (🛺)
-1F6FB..1F6FC ; Basic_Emoji ; pickup truck # E13.0 [2] (🛻..🛼)
-1F7E0..1F7EB ; Basic_Emoji ; orange circle # E12.0 [12] (🟠..🟫)
+1F6FB..1F6FC ; Basic_Emoji ; pickup truck..roller skate # E13.0 [2] (🛻..🛼)
+1F7E0..1F7EB ; Basic_Emoji ; orange circle..brown square # E12.0 [12] (🟠..🟫)
1F7F0 ; Basic_Emoji ; heavy equals sign # E14.0 [1] (🟰)
1F90C ; Basic_Emoji ; pinched fingers # E13.0 [1] (🤌)
-1F90D..1F90F ; Basic_Emoji ; white heart # E12.0 [3] (🤍..🤏)
-1F910..1F918 ; Basic_Emoji ; zipper-mouth face # E1.0 [9] (🤐..🤘)
-1F919..1F91E ; Basic_Emoji ; call me hand # E3.0 [6] (🤙..🤞)
+1F90D..1F90F ; Basic_Emoji ; white heart..pinching hand # E12.0 [3] (🤍..🤏)
+1F910..1F918 ; Basic_Emoji ; zipper-mouth face..sign of the horns # E1.0 [9] (🤐..🤘)
+1F919..1F91E ; Basic_Emoji ; call me hand..crossed fingers # E3.0 [6] (🤙..🤞)
1F91F ; Basic_Emoji ; love-you gesture # E5.0 [1] (🤟)
-1F920..1F927 ; Basic_Emoji ; cowboy hat face # E3.0 [8] (🤠..🤧)
-1F928..1F92F ; Basic_Emoji ; face with raised eyebrow # E5.0 [8] (🤨..🤯)
+1F920..1F927 ; Basic_Emoji ; cowboy hat face..sneezing face # E3.0 [8] (🤠..🤧)
+1F928..1F92F ; Basic_Emoji ; face with raised eyebrow..exploding head # E5.0 [8] (🤨..🤯)
1F930 ; Basic_Emoji ; pregnant woman # E3.0 [1] (🤰)
-1F931..1F932 ; Basic_Emoji ; breast-feeding # E5.0 [2] (🤱..🤲)
-1F933..1F93A ; Basic_Emoji ; selfie # E3.0 [8] (🤳..🤺)
-1F93C..1F93E ; Basic_Emoji ; people wrestling # E3.0 [3] (🤼..🤾)
+1F931..1F932 ; Basic_Emoji ; breast-feeding..palms up together # E5.0 [2] (🤱..🤲)
+1F933..1F93A ; Basic_Emoji ; selfie..person fencing # E3.0 [8] (🤳..🤺)
+1F93C..1F93E ; Basic_Emoji ; people wrestling..person playing handball # E3.0 [3] (🤼..🤾)
1F93F ; Basic_Emoji ; diving mask # E12.0 [1] (🤿)
-1F940..1F945 ; Basic_Emoji ; wilted flower # E3.0 [6] (🥀..🥅)
-1F947..1F94B ; Basic_Emoji ; 1st place medal # E3.0 [5] (🥇..🥋)
+1F940..1F945 ; Basic_Emoji ; wilted flower..goal net # E3.0 [6] (🥀..🥅)
+1F947..1F94B ; Basic_Emoji ; 1st place medal..martial arts uniform # E3.0 [5] (🥇..🥋)
1F94C ; Basic_Emoji ; curling stone # E5.0 [1] (🥌)
-1F94D..1F94F ; Basic_Emoji ; lacrosse # E11.0 [3] (🥍..🥏)
-1F950..1F95E ; Basic_Emoji ; croissant # E3.0 [15] (🥐..🥞)
-1F95F..1F96B ; Basic_Emoji ; dumpling # E5.0 [13] (🥟..🥫)
-1F96C..1F970 ; Basic_Emoji ; leafy green # E11.0 [5] (🥬..🥰)
+1F94D..1F94F ; Basic_Emoji ; lacrosse..flying disc # E11.0 [3] (🥍..🥏)
+1F950..1F95E ; Basic_Emoji ; croissant..pancakes # E3.0 [15] (🥐..🥞)
+1F95F..1F96B ; Basic_Emoji ; dumpling..canned food # E5.0 [13] (🥟..🥫)
+1F96C..1F970 ; Basic_Emoji ; leafy green..smiling face with hearts # E11.0 [5] (🥬..🥰)
1F971 ; Basic_Emoji ; yawning face # E12.0 [1] (🥱)
1F972 ; Basic_Emoji ; smiling face with tear # E13.0 [1] (🥲)
-1F973..1F976 ; Basic_Emoji ; partying face # E11.0 [4] (🥳..🥶)
-1F977..1F978 ; Basic_Emoji ; ninja # E13.0 [2] (🥷..🥸)
+1F973..1F976 ; Basic_Emoji ; partying face..cold face # E11.0 [4] (🥳..🥶)
+1F977..1F978 ; Basic_Emoji ; ninja..disguised face # E13.0 [2] (🥷..🥸)
1F979 ; Basic_Emoji ; face holding back tears # E14.0 [1] (🥹)
1F97A ; Basic_Emoji ; pleading face # E11.0 [1] (🥺)
1F97B ; Basic_Emoji ; sari # E12.0 [1] (🥻)
-1F97C..1F97F ; Basic_Emoji ; lab coat # E11.0 [4] (🥼..🥿)
-1F980..1F984 ; Basic_Emoji ; crab # E1.0 [5] (🦀..🦄)
-1F985..1F991 ; Basic_Emoji ; eagle # E3.0 [13] (🦅..🦑)
-1F992..1F997 ; Basic_Emoji ; giraffe # E5.0 [6] (🦒..🦗)
-1F998..1F9A2 ; Basic_Emoji ; kangaroo # E11.0 [11] (🦘..🦢)
-1F9A3..1F9A4 ; Basic_Emoji ; mammoth # E13.0 [2] (🦣..🦤)
-1F9A5..1F9AA ; Basic_Emoji ; sloth # E12.0 [6] (🦥..🦪)
-1F9AB..1F9AD ; Basic_Emoji ; beaver # E13.0 [3] (🦫..🦭)
-1F9AE..1F9AF ; Basic_Emoji ; guide dog # E12.0 [2] (🦮..🦯)
-1F9B0..1F9B9 ; Basic_Emoji ; red hair # E11.0 [10] (🦰..🦹)
-1F9BA..1F9BF ; Basic_Emoji ; safety vest # E12.0 [6] (🦺..🦿)
+1F97C..1F97F ; Basic_Emoji ; lab coat..flat shoe # E11.0 [4] (🥼..🥿)
+1F980..1F984 ; Basic_Emoji ; crab..unicorn # E1.0 [5] (🦀..🦄)
+1F985..1F991 ; Basic_Emoji ; eagle..squid # E3.0 [13] (🦅..🦑)
+1F992..1F997 ; Basic_Emoji ; giraffe..cricket # E5.0 [6] (🦒..🦗)
+1F998..1F9A2 ; Basic_Emoji ; kangaroo..swan # E11.0 [11] (🦘..🦢)
+1F9A3..1F9A4 ; Basic_Emoji ; mammoth..dodo # E13.0 [2] (🦣..🦤)
+1F9A5..1F9AA ; Basic_Emoji ; sloth..oyster # E12.0 [6] (🦥..🦪)
+1F9AB..1F9AD ; Basic_Emoji ; beaver..seal # E13.0 [3] (🦫..🦭)
+1F9AE..1F9AF ; Basic_Emoji ; guide dog..white cane # E12.0 [2] (🦮..🦯)
+1F9B0..1F9B9 ; Basic_Emoji ; red hair..supervillain # E11.0 [10] (🦰..🦹)
+1F9BA..1F9BF ; Basic_Emoji ; safety vest..mechanical leg # E12.0 [6] (🦺..🦿)
1F9C0 ; Basic_Emoji ; cheese wedge # E1.0 [1] (🧀)
-1F9C1..1F9C2 ; Basic_Emoji ; cupcake # E11.0 [2] (🧁..🧂)
-1F9C3..1F9CA ; Basic_Emoji ; beverage box # E12.0 [8] (🧃..🧊)
+1F9C1..1F9C2 ; Basic_Emoji ; cupcake..salt # E11.0 [2] (🧁..🧂)
+1F9C3..1F9CA ; Basic_Emoji ; beverage box..ice # E12.0 [8] (🧃..🧊)
1F9CB ; Basic_Emoji ; bubble tea # E13.0 [1] (🧋)
1F9CC ; Basic_Emoji ; troll # E14.0 [1] (🧌)
-1F9CD..1F9CF ; Basic_Emoji ; person standing # E12.0 [3] (🧍..🧏)
-1F9D0..1F9E6 ; Basic_Emoji ; face with monocle # E5.0 [23] (🧐..🧦)
-1F9E7..1F9FF ; Basic_Emoji ; red envelope # E11.0 [25] (🧧..🧿)
-1FA70..1FA73 ; Basic_Emoji ; ballet shoes # E12.0 [4] (🩰..🩳)
+1F9CD..1F9CF ; Basic_Emoji ; person standing..deaf person # E12.0 [3] (🧍..🧏)
+1F9D0..1F9E6 ; Basic_Emoji ; face with monocle..socks # E5.0 [23] (🧐..🧦)
+1F9E7..1F9FF ; Basic_Emoji ; red envelope..nazar amulet # E11.0 [25] (🧧..🧿)
+1FA70..1FA73 ; Basic_Emoji ; ballet shoes..shorts # E12.0 [4] (🩰..🩳)
1FA74 ; Basic_Emoji ; thong sandal # E13.0 [1] (🩴)
-1FA78..1FA7A ; Basic_Emoji ; drop of blood # E12.0 [3] (🩸..🩺)
-1FA7B..1FA7C ; Basic_Emoji ; x-ray # E14.0 [2] (🩻..🩼)
-1FA80..1FA82 ; Basic_Emoji ; yo-yo # E12.0 [3] (🪀..🪂)
-1FA83..1FA86 ; Basic_Emoji ; boomerang # E13.0 [4] (🪃..🪆)
-1FA90..1FA95 ; Basic_Emoji ; ringed planet # E12.0 [6] (🪐..🪕)
-1FA96..1FAA8 ; Basic_Emoji ; military helmet # E13.0 [19] (🪖..🪨)
-1FAA9..1FAAC ; Basic_Emoji ; mirror ball # E14.0 [4] (🪩..🪬)
-1FAB0..1FAB6 ; Basic_Emoji ; fly # E13.0 [7] (🪰..🪶)
-1FAB7..1FABA ; Basic_Emoji ; lotus # E14.0 [4] (🪷..🪺)
-1FAC0..1FAC2 ; Basic_Emoji ; anatomical heart # E13.0 [3] (🫀..🫂)
-1FAC3..1FAC5 ; Basic_Emoji ; pregnant man # E14.0 [3] (🫃..🫅)
-1FAD0..1FAD6 ; Basic_Emoji ; blueberries # E13.0 [7] (🫐..🫖)
-1FAD7..1FAD9 ; Basic_Emoji ; pouring liquid # E14.0 [3] (🫗..🫙)
-1FAE0..1FAE7 ; Basic_Emoji ; melting face # E14.0 [8] (🫠..🫧)
-1FAF0..1FAF6 ; Basic_Emoji ; hand with index finger and thumb crossed # E14.0 [7] (🫰..🫶)
+1FA75..1FA77 ; Basic_Emoji ; light blue heart..pink heart # E15.0 [3] (🩵..🩷)
+1FA78..1FA7A ; Basic_Emoji ; drop of blood..stethoscope # E12.0 [3] (🩸..🩺)
+1FA7B..1FA7C ; Basic_Emoji ; x-ray..crutch # E14.0 [2] (🩻..🩼)
+1FA80..1FA82 ; Basic_Emoji ; yo-yo..parachute # E12.0 [3] (🪀..🪂)
+1FA83..1FA86 ; Basic_Emoji ; boomerang..nesting dolls # E13.0 [4] (🪃..🪆)
+1FA87..1FA88 ; Basic_Emoji ; maracas..flute # E15.0 [2] (🪇..🪈)
+1FA90..1FA95 ; Basic_Emoji ; ringed planet..banjo # E12.0 [6] (🪐..🪕)
+1FA96..1FAA8 ; Basic_Emoji ; military helmet..rock # E13.0 [19] (🪖..🪨)
+1FAA9..1FAAC ; Basic_Emoji ; mirror ball..hamsa # E14.0 [4] (🪩..🪬)
+1FAAD..1FAAF ; Basic_Emoji ; folding hand fan..khanda # E15.0 [3] (🪭..🪯)
+1FAB0..1FAB6 ; Basic_Emoji ; fly..feather # E13.0 [7] (🪰..🪶)
+1FAB7..1FABA ; Basic_Emoji ; lotus..nest with eggs # E14.0 [4] (🪷..🪺)
+1FABB..1FABD ; Basic_Emoji ; hyacinth..wing # E15.0 [3] (🪻..🪽)
+1FABF ; Basic_Emoji ; goose # E15.0 [1] (🪿)
+1FAC0..1FAC2 ; Basic_Emoji ; anatomical heart..people hugging # E13.0 [3] (🫀..🫂)
+1FAC3..1FAC5 ; Basic_Emoji ; pregnant man..person with crown # E14.0 [3] (🫃..🫅)
+1FACE..1FACF ; Basic_Emoji ; moose..donkey # E15.0 [2] (🫎..🫏)
+1FAD0..1FAD6 ; Basic_Emoji ; blueberries..teapot # E13.0 [7] (🫐..🫖)
+1FAD7..1FAD9 ; Basic_Emoji ; pouring liquid..jar # E14.0 [3] (🫗..🫙)
+1FADA..1FADB ; Basic_Emoji ; ginger root..pea pod # E15.0 [2] (🫚..🫛)
+1FAE0..1FAE7 ; Basic_Emoji ; melting face..bubbles # E14.0 [8] (🫠..🫧)
+1FAE8 ; Basic_Emoji ; shaking face # E15.0 [1] (🫨)
+1FAF0..1FAF6 ; Basic_Emoji ; hand with index finger and thumb crossed..heart hands # E14.0 [7] (🫰..🫶)
+1FAF7..1FAF8 ; Basic_Emoji ; leftwards pushing hand..rightwards pushing hand # E15.0 [2] (🫷..🫸)
00A9 FE0F ; Basic_Emoji ; copyright # E0.6 [1] (©️)
00AE FE0F ; Basic_Emoji ; registered # E0.6 [1] (®️)
203C FE0F ; Basic_Emoji ; double exclamation mark # E0.6 [1] (‼️)
@@ -517,12 +528,13 @@
1F6F0 FE0F ; Basic_Emoji ; satellite # E0.7 [1] (🛰️)
1F6F3 FE0F ; Basic_Emoji ; passenger ship # E0.7 [1] (🛳️)
-# Total elements: 1366
+# Total elements: 1386
# ================================================
# Emoji_Keycap_Sequence
+
0023 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: \x{23} # E0.6 [1] (#️⃣)
002A FE0F 20E3; Emoji_Keycap_Sequence ; keycap: * # E2.0 [1] (*️⃣)
0030 FE0F 20E3; Emoji_Keycap_Sequence ; keycap: 0 # E0.6 [1] (0️⃣)
@@ -543,6 +555,7 @@
# RGI_Emoji_Flag_Sequence: This list does not include deprecated or macroregion flags, except for UN and EU.
# See Annex B of TR51 for more information.
+
1F1E6 1F1E8 ; RGI_Emoji_Flag_Sequence ; flag: Ascension Island # E2.0 [1] (🇦🇨)
1F1E6 1F1E9 ; RGI_Emoji_Flag_Sequence ; flag: Andorra # E2.0 [1] (🇦🇩)
1F1E6 1F1EA ; RGI_Emoji_Flag_Sequence ; flag: United Arab Emirates # E2.0 [1] (🇦🇪)
@@ -808,6 +821,7 @@
# RGI_Emoji_Tag_Sequence: See Annex C of TR51 for more information.
+
1F3F4 E0067 E0062 E0065 E006E E0067 E007F; RGI_Emoji_Tag_Sequence; flag: England # E5.0 [1] (🏴󠁧󠁢󠁥󠁮󠁧󠁿)
1F3F4 E0067 E0062 E0073 E0063 E0074 E007F; RGI_Emoji_Tag_Sequence; flag: Scotland # E5.0 [1] (🏴󠁧󠁢󠁳󠁣󠁴󠁿)
1F3F4 E0067 E0062 E0077 E006C E0073 E007F; RGI_Emoji_Tag_Sequence; flag: Wales # E5.0 [1] (🏴󠁧󠁢󠁷󠁬󠁳󠁿)
@@ -818,6 +832,7 @@
# RGI_Emoji_Modifier_Sequence
+
261D 1F3FB ; RGI_Emoji_Modifier_Sequence ; index pointing up: light skin tone # E1.0 [1] (☝🏻)
261D 1F3FC ; RGI_Emoji_Modifier_Sequence ; index pointing up: medium-light skin tone # E1.0 [1] (☝🏼)
261D 1F3FD ; RGI_Emoji_Modifier_Sequence ; index pointing up: medium skin tone # E1.0 [1] (☝🏽)
@@ -1223,11 +1238,11 @@
1F91C 1F3FD ; RGI_Emoji_Modifier_Sequence ; right-facing fist: medium skin tone # E3.0 [1] (🤜🏽)
1F91C 1F3FE ; RGI_Emoji_Modifier_Sequence ; right-facing fist: medium-dark skin tone # E3.0 [1] (🤜🏾)
1F91C 1F3FF ; RGI_Emoji_Modifier_Sequence ; right-facing fist: dark skin tone # E3.0 [1] (🤜🏿)
-1F91D 1F3FB ; RGI_Emoji_Modifier_Sequence ; handshake: light skin tone # E3.0 [1] (🤝🏻)
-1F91D 1F3FC ; RGI_Emoji_Modifier_Sequence ; handshake: medium-light skin tone # E3.0 [1] (🤝🏼)
-1F91D 1F3FD ; RGI_Emoji_Modifier_Sequence ; handshake: medium skin tone # E3.0 [1] (🤝🏽)
-1F91D 1F3FE ; RGI_Emoji_Modifier_Sequence ; handshake: medium-dark skin tone # E3.0 [1] (🤝🏾)
-1F91D 1F3FF ; RGI_Emoji_Modifier_Sequence ; handshake: dark skin tone # E3.0 [1] (🤝🏿)
+1F91D 1F3FB ; RGI_Emoji_Modifier_Sequence ; handshake: light skin tone # E14.0 [1] (🤝🏻)
+1F91D 1F3FC ; RGI_Emoji_Modifier_Sequence ; handshake: medium-light skin tone # E14.0 [1] (🤝🏼)
+1F91D 1F3FD ; RGI_Emoji_Modifier_Sequence ; handshake: medium skin tone # E14.0 [1] (🤝🏽)
+1F91D 1F3FE ; RGI_Emoji_Modifier_Sequence ; handshake: medium-dark skin tone # E14.0 [1] (🤝🏾)
+1F91D 1F3FF ; RGI_Emoji_Modifier_Sequence ; handshake: dark skin tone # E14.0 [1] (🤝🏿)
1F91E 1F3FB ; RGI_Emoji_Modifier_Sequence ; crossed fingers: light skin tone # E3.0 [1] (🤞🏻)
1F91E 1F3FC ; RGI_Emoji_Modifier_Sequence ; crossed fingers: medium-light skin tone # E3.0 [1] (🤞🏼)
1F91E 1F3FD ; RGI_Emoji_Modifier_Sequence ; crossed fingers: medium skin tone # E3.0 [1] (🤞🏽)
@@ -1463,7 +1478,17 @@
1FAF6 1F3FD ; RGI_Emoji_Modifier_Sequence ; heart hands: medium skin tone # E14.0 [1] (🫶🏽)
1FAF6 1F3FE ; RGI_Emoji_Modifier_Sequence ; heart hands: medium-dark skin tone # E14.0 [1] (🫶🏾)
1FAF6 1F3FF ; RGI_Emoji_Modifier_Sequence ; heart hands: dark skin tone # E14.0 [1] (🫶🏿)
+1FAF7 1F3FB ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: light skin tone # E15.0 [1] (🫷🏻)
+1FAF7 1F3FC ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: medium-light skin tone # E15.0 [1] (🫷🏼)
+1FAF7 1F3FD ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: medium skin tone # E15.0 [1] (🫷🏽)
+1FAF7 1F3FE ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: medium-dark skin tone # E15.0 [1] (🫷🏾)
+1FAF7 1F3FF ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: dark skin tone # E15.0 [1] (🫷🏿)
+1FAF8 1F3FB ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: light skin tone # E15.0 [1] (🫸🏻)
+1FAF8 1F3FC ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: medium-light skin tone # E15.0 [1] (🫸🏼)
+1FAF8 1F3FD ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: medium skin tone # E15.0 [1] (🫸🏽)
+1FAF8 1F3FE ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: medium-dark skin tone # E15.0 [1] (🫸🏾)
+1FAF8 1F3FF ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: dark skin tone # E15.0 [1] (🫸🏿)
-# Total elements: 645
+# Total elements: 655
#EOF
diff --git a/admin/unidata/emoji-test.txt b/admin/unidata/emoji-test.txt
index 42e6210cd28..bc8b52c2fb4 100644
--- a/admin/unidata/emoji-test.txt
+++ b/admin/unidata/emoji-test.txt
@@ -1,13 +1,13 @@
# emoji-test.txt
-# Date: 2021-08-26, 17:22:23 GMT
-# © 2021 Unicode®, Inc.
+# Date: 2022-08-12, 20:24:39 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Emoji Keyboard/Display Test Data for UTS #51
-# Version: 14.0
+# Version: 15.0
#
-# For documentation and usage, see http://www.unicode.org/reports/tr51
+# For documentation and usage, see https://www.unicode.org/reports/tr51
#
# This file provides data for testing which emoji forms should be in keyboards and which should also be displayed/processed.
# Format: code points; status # emoji name
@@ -92,6 +92,7 @@
1F62C ; fully-qualified # 😬 E1.0 grimacing face
1F62E 200D 1F4A8 ; fully-qualified # 😮‍💨 E13.1 face exhaling
1F925 ; fully-qualified # 🤥 E3.0 lying face
+1FAE8 ; fully-qualified # 🫨 E15.0 shaking face
# subgroup: face-sleepy
1F60C ; fully-qualified # 😌 E0.6 relieved face
@@ -155,7 +156,7 @@
# subgroup: face-negative
1F624 ; fully-qualified # 😤 E0.6 face with steam from nose
-1F621 ; fully-qualified # 😡 E0.6 pouting face
+1F621 ; fully-qualified # 😡 E0.6 enraged face
1F620 ; fully-qualified # 😠 E0.6 angry face
1F92C ; fully-qualified # 🤬 E5.0 face with symbols on mouth
1F608 ; fully-qualified # 😈 E1.0 smiling face with horns
@@ -190,8 +191,7 @@
1F649 ; fully-qualified # 🙉 E0.6 hear-no-evil monkey
1F64A ; fully-qualified # 🙊 E0.6 speak-no-evil monkey
-# subgroup: emotion
-1F48B ; fully-qualified # 💋 E0.6 kiss mark
+# subgroup: heart
1F48C ; fully-qualified # 💌 E0.6 love letter
1F498 ; fully-qualified # 💘 E0.6 heart with arrow
1F49D ; fully-qualified # 💝 E0.6 heart with ribbon
@@ -210,14 +210,20 @@
2764 200D 1FA79 ; unqualified # ❤‍🩹 E13.1 mending heart
2764 FE0F ; fully-qualified # ❤️ E0.6 red heart
2764 ; unqualified # ❤ E0.6 red heart
+1FA77 ; fully-qualified # 🩷 E15.0 pink heart
1F9E1 ; fully-qualified # 🧡 E5.0 orange heart
1F49B ; fully-qualified # 💛 E0.6 yellow heart
1F49A ; fully-qualified # 💚 E0.6 green heart
1F499 ; fully-qualified # 💙 E0.6 blue heart
+1FA75 ; fully-qualified # 🩵 E15.0 light blue heart
1F49C ; fully-qualified # 💜 E0.6 purple heart
1F90E ; fully-qualified # 🤎 E12.0 brown heart
1F5A4 ; fully-qualified # 🖤 E3.0 black heart
+1FA76 ; fully-qualified # 🩶 E15.0 grey heart
1F90D ; fully-qualified # 🤍 E12.0 white heart
+
+# subgroup: emotion
+1F48B ; fully-qualified # 💋 E0.6 kiss mark
1F4AF ; fully-qualified # 💯 E0.6 hundred points
1F4A2 ; fully-qualified # 💢 E0.6 anger symbol
1F4A5 ; fully-qualified # 💥 E0.6 collision
@@ -226,21 +232,20 @@
1F4A8 ; fully-qualified # 💨 E0.6 dashing away
1F573 FE0F ; fully-qualified # 🕳️ E0.7 hole
1F573 ; unqualified # 🕳 E0.7 hole
-1F4A3 ; fully-qualified # 💣 E0.6 bomb
1F4AC ; fully-qualified # 💬 E0.6 speech balloon
1F441 FE0F 200D 1F5E8 FE0F ; fully-qualified # 👁️‍🗨️ E2.0 eye in speech bubble
1F441 200D 1F5E8 FE0F ; unqualified # 👁‍🗨️ E2.0 eye in speech bubble
-1F441 FE0F 200D 1F5E8 ; unqualified # 👁️‍🗨 E2.0 eye in speech bubble
+1F441 FE0F 200D 1F5E8 ; minimally-qualified # 👁️‍🗨 E2.0 eye in speech bubble
1F441 200D 1F5E8 ; unqualified # 👁‍🗨 E2.0 eye in speech bubble
1F5E8 FE0F ; fully-qualified # 🗨️ E2.0 left speech bubble
1F5E8 ; unqualified # 🗨 E2.0 left speech bubble
1F5EF FE0F ; fully-qualified # 🗯️ E0.7 right anger bubble
1F5EF ; unqualified # 🗯 E0.7 right anger bubble
1F4AD ; fully-qualified # 💭 E1.0 thought balloon
-1F4A4 ; fully-qualified # 💤 E0.6 zzz
+1F4A4 ; fully-qualified # 💤 E0.6 ZZZ
-# Smileys & Emotion subtotal: 177
-# Smileys & Emotion subtotal: 177 w/o modifiers
+# Smileys & Emotion subtotal: 180
+# Smileys & Emotion subtotal: 180 w/o modifiers
# group: People & Body
@@ -300,6 +305,18 @@
1FAF4 1F3FD ; fully-qualified # 🫴🏽 E14.0 palm up hand: medium skin tone
1FAF4 1F3FE ; fully-qualified # 🫴🏾 E14.0 palm up hand: medium-dark skin tone
1FAF4 1F3FF ; fully-qualified # 🫴🏿 E14.0 palm up hand: dark skin tone
+1FAF7 ; fully-qualified # 🫷 E15.0 leftwards pushing hand
+1FAF7 1F3FB ; fully-qualified # 🫷🏻 E15.0 leftwards pushing hand: light skin tone
+1FAF7 1F3FC ; fully-qualified # 🫷🏼 E15.0 leftwards pushing hand: medium-light skin tone
+1FAF7 1F3FD ; fully-qualified # 🫷🏽 E15.0 leftwards pushing hand: medium skin tone
+1FAF7 1F3FE ; fully-qualified # 🫷🏾 E15.0 leftwards pushing hand: medium-dark skin tone
+1FAF7 1F3FF ; fully-qualified # 🫷🏿 E15.0 leftwards pushing hand: dark skin tone
+1FAF8 ; fully-qualified # 🫸 E15.0 rightwards pushing hand
+1FAF8 1F3FB ; fully-qualified # 🫸🏻 E15.0 rightwards pushing hand: light skin tone
+1FAF8 1F3FC ; fully-qualified # 🫸🏼 E15.0 rightwards pushing hand: medium-light skin tone
+1FAF8 1F3FD ; fully-qualified # 🫸🏽 E15.0 rightwards pushing hand: medium skin tone
+1FAF8 1F3FE ; fully-qualified # 🫸🏾 E15.0 rightwards pushing hand: medium-dark skin tone
+1FAF8 1F3FF ; fully-qualified # 🫸🏿 E15.0 rightwards pushing hand: dark skin tone
# subgroup: hand-fingers-partial
1F44C ; fully-qualified # 👌 E0.6 OK hand
@@ -473,11 +490,11 @@
1F932 1F3FE ; fully-qualified # 🤲🏾 E5.0 palms up together: medium-dark skin tone
1F932 1F3FF ; fully-qualified # 🤲🏿 E5.0 palms up together: dark skin tone
1F91D ; fully-qualified # 🤝 E3.0 handshake
-1F91D 1F3FB ; fully-qualified # 🤝🏻 E3.0 handshake: light skin tone
-1F91D 1F3FC ; fully-qualified # 🤝🏼 E3.0 handshake: medium-light skin tone
-1F91D 1F3FD ; fully-qualified # 🤝🏽 E3.0 handshake: medium skin tone
-1F91D 1F3FE ; fully-qualified # 🤝🏾 E3.0 handshake: medium-dark skin tone
-1F91D 1F3FF ; fully-qualified # 🤝🏿 E3.0 handshake: dark skin tone
+1F91D 1F3FB ; fully-qualified # 🤝🏻 E14.0 handshake: light skin tone
+1F91D 1F3FC ; fully-qualified # 🤝🏼 E14.0 handshake: medium-light skin tone
+1F91D 1F3FD ; fully-qualified # 🤝🏽 E14.0 handshake: medium skin tone
+1F91D 1F3FE ; fully-qualified # 🤝🏾 E14.0 handshake: medium-dark skin tone
+1F91D 1F3FF ; fully-qualified # 🤝🏿 E14.0 handshake: dark skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FC ; fully-qualified # 🫱🏻‍🫲🏼 E14.0 handshake: light skin tone, medium-light skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FD ; fully-qualified # 🫱🏻‍🫲🏽 E14.0 handshake: light skin tone, medium skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FE ; fully-qualified # 🫱🏻‍🫲🏾 E14.0 handshake: light skin tone, medium-dark skin tone
@@ -1455,7 +1472,7 @@
1F575 1F3FF ; fully-qualified # 🕵🏿 E2.0 detective: dark skin tone
1F575 FE0F 200D 2642 FE0F ; fully-qualified # 🕵️‍♂️ E4.0 man detective
1F575 200D 2642 FE0F ; unqualified # 🕵‍♂️ E4.0 man detective
-1F575 FE0F 200D 2642 ; unqualified # 🕵️‍♂ E4.0 man detective
+1F575 FE0F 200D 2642 ; minimally-qualified # 🕵️‍♂ E4.0 man detective
1F575 200D 2642 ; unqualified # 🕵‍♂ E4.0 man detective
1F575 1F3FB 200D 2642 FE0F ; fully-qualified # 🕵🏻‍♂️ E4.0 man detective: light skin tone
1F575 1F3FB 200D 2642 ; minimally-qualified # 🕵🏻‍♂ E4.0 man detective: light skin tone
@@ -1469,7 +1486,7 @@
1F575 1F3FF 200D 2642 ; minimally-qualified # 🕵🏿‍♂ E4.0 man detective: dark skin tone
1F575 FE0F 200D 2640 FE0F ; fully-qualified # 🕵️‍♀️ E4.0 woman detective
1F575 200D 2640 FE0F ; unqualified # 🕵‍♀️ E4.0 woman detective
-1F575 FE0F 200D 2640 ; unqualified # 🕵️‍♀ E4.0 woman detective
+1F575 FE0F 200D 2640 ; minimally-qualified # 🕵️‍♀ E4.0 woman detective
1F575 200D 2640 ; unqualified # 🕵‍♀ E4.0 woman detective
1F575 1F3FB 200D 2640 FE0F ; fully-qualified # 🕵🏻‍♀️ E4.0 woman detective: light skin tone
1F575 1F3FB 200D 2640 ; minimally-qualified # 🕵🏻‍♀ E4.0 woman detective: light skin tone
@@ -2302,7 +2319,7 @@
1F3CC 1F3FF ; fully-qualified # 🏌🏿 E4.0 person golfing: dark skin tone
1F3CC FE0F 200D 2642 FE0F ; fully-qualified # 🏌️‍♂️ E4.0 man golfing
1F3CC 200D 2642 FE0F ; unqualified # 🏌‍♂️ E4.0 man golfing
-1F3CC FE0F 200D 2642 ; unqualified # 🏌️‍♂ E4.0 man golfing
+1F3CC FE0F 200D 2642 ; minimally-qualified # 🏌️‍♂ E4.0 man golfing
1F3CC 200D 2642 ; unqualified # 🏌‍♂ E4.0 man golfing
1F3CC 1F3FB 200D 2642 FE0F ; fully-qualified # 🏌🏻‍♂️ E4.0 man golfing: light skin tone
1F3CC 1F3FB 200D 2642 ; minimally-qualified # 🏌🏻‍♂ E4.0 man golfing: light skin tone
@@ -2316,7 +2333,7 @@
1F3CC 1F3FF 200D 2642 ; minimally-qualified # 🏌🏿‍♂ E4.0 man golfing: dark skin tone
1F3CC FE0F 200D 2640 FE0F ; fully-qualified # 🏌️‍♀️ E4.0 woman golfing
1F3CC 200D 2640 FE0F ; unqualified # 🏌‍♀️ E4.0 woman golfing
-1F3CC FE0F 200D 2640 ; unqualified # 🏌️‍♀ E4.0 woman golfing
+1F3CC FE0F 200D 2640 ; minimally-qualified # 🏌️‍♀ E4.0 woman golfing
1F3CC 200D 2640 ; unqualified # 🏌‍♀ E4.0 woman golfing
1F3CC 1F3FB 200D 2640 FE0F ; fully-qualified # 🏌🏻‍♀️ E4.0 woman golfing: light skin tone
1F3CC 1F3FB 200D 2640 ; minimally-qualified # 🏌🏻‍♀ E4.0 woman golfing: light skin tone
@@ -2427,7 +2444,7 @@
26F9 1F3FF ; fully-qualified # ⛹🏿 E2.0 person bouncing ball: dark skin tone
26F9 FE0F 200D 2642 FE0F ; fully-qualified # ⛹️‍♂️ E4.0 man bouncing ball
26F9 200D 2642 FE0F ; unqualified # ⛹‍♂️ E4.0 man bouncing ball
-26F9 FE0F 200D 2642 ; unqualified # ⛹️‍♂ E4.0 man bouncing ball
+26F9 FE0F 200D 2642 ; minimally-qualified # ⛹️‍♂ E4.0 man bouncing ball
26F9 200D 2642 ; unqualified # ⛹‍♂ E4.0 man bouncing ball
26F9 1F3FB 200D 2642 FE0F ; fully-qualified # ⛹🏻‍♂️ E4.0 man bouncing ball: light skin tone
26F9 1F3FB 200D 2642 ; minimally-qualified # ⛹🏻‍♂ E4.0 man bouncing ball: light skin tone
@@ -2441,7 +2458,7 @@
26F9 1F3FF 200D 2642 ; minimally-qualified # ⛹🏿‍♂ E4.0 man bouncing ball: dark skin tone
26F9 FE0F 200D 2640 FE0F ; fully-qualified # ⛹️‍♀️ E4.0 woman bouncing ball
26F9 200D 2640 FE0F ; unqualified # ⛹‍♀️ E4.0 woman bouncing ball
-26F9 FE0F 200D 2640 ; unqualified # ⛹️‍♀ E4.0 woman bouncing ball
+26F9 FE0F 200D 2640 ; minimally-qualified # ⛹️‍♀ E4.0 woman bouncing ball
26F9 200D 2640 ; unqualified # ⛹‍♀ E4.0 woman bouncing ball
26F9 1F3FB 200D 2640 FE0F ; fully-qualified # ⛹🏻‍♀️ E4.0 woman bouncing ball: light skin tone
26F9 1F3FB 200D 2640 ; minimally-qualified # ⛹🏻‍♀ E4.0 woman bouncing ball: light skin tone
@@ -2462,7 +2479,7 @@
1F3CB 1F3FF ; fully-qualified # 🏋🏿 E2.0 person lifting weights: dark skin tone
1F3CB FE0F 200D 2642 FE0F ; fully-qualified # 🏋️‍♂️ E4.0 man lifting weights
1F3CB 200D 2642 FE0F ; unqualified # 🏋‍♂️ E4.0 man lifting weights
-1F3CB FE0F 200D 2642 ; unqualified # 🏋️‍♂ E4.0 man lifting weights
+1F3CB FE0F 200D 2642 ; minimally-qualified # 🏋️‍♂ E4.0 man lifting weights
1F3CB 200D 2642 ; unqualified # 🏋‍♂ E4.0 man lifting weights
1F3CB 1F3FB 200D 2642 FE0F ; fully-qualified # 🏋🏻‍♂️ E4.0 man lifting weights: light skin tone
1F3CB 1F3FB 200D 2642 ; minimally-qualified # 🏋🏻‍♂ E4.0 man lifting weights: light skin tone
@@ -2476,7 +2493,7 @@
1F3CB 1F3FF 200D 2642 ; minimally-qualified # 🏋🏿‍♂ E4.0 man lifting weights: dark skin tone
1F3CB FE0F 200D 2640 FE0F ; fully-qualified # 🏋️‍♀️ E4.0 woman lifting weights
1F3CB 200D 2640 FE0F ; unqualified # 🏋‍♀️ E4.0 woman lifting weights
-1F3CB FE0F 200D 2640 ; unqualified # 🏋️‍♀ E4.0 woman lifting weights
+1F3CB FE0F 200D 2640 ; minimally-qualified # 🏋️‍♀ E4.0 woman lifting weights
1F3CB 200D 2640 ; unqualified # 🏋‍♀ E4.0 woman lifting weights
1F3CB 1F3FB 200D 2640 FE0F ; fully-qualified # 🏋🏻‍♀️ E4.0 woman lifting weights: light skin tone
1F3CB 1F3FB 200D 2640 ; minimally-qualified # 🏋🏻‍♀ E4.0 woman lifting weights: light skin tone
@@ -3262,8 +3279,8 @@
1FAC2 ; fully-qualified # 🫂 E13.0 people hugging
1F463 ; fully-qualified # 👣 E0.6 footprints
-# People & Body subtotal: 2986
-# People & Body subtotal: 506 w/o modifiers
+# People & Body subtotal: 2998
+# People & Body subtotal: 508 w/o modifiers
# group: Component
@@ -3306,6 +3323,8 @@
1F405 ; fully-qualified # 🐅 E1.0 tiger
1F406 ; fully-qualified # 🐆 E1.0 leopard
1F434 ; fully-qualified # 🐴 E0.6 horse face
+1FACE ; fully-qualified # 🫎 E15.0 moose
+1FACF ; fully-qualified # 🫏 E15.0 donkey
1F40E ; fully-qualified # 🐎 E0.6 horse
1F984 ; fully-qualified # 🦄 E1.0 unicorn
1F993 ; fully-qualified # 🦓 E5.0 zebra
@@ -3373,6 +3392,9 @@
1F9A9 ; fully-qualified # 🦩 E12.0 flamingo
1F99A ; fully-qualified # 🦚 E11.0 peacock
1F99C ; fully-qualified # 🦜 E11.0 parrot
+1FABD ; fully-qualified # 🪽 E15.0 wing
+1F426 200D 2B1B ; fully-qualified # 🐦‍⬛ E15.0 black bird
+1FABF ; fully-qualified # 🪿 E15.0 goose
# subgroup: animal-amphibian
1F438 ; fully-qualified # 🐸 E0.6 frog
@@ -3399,6 +3421,7 @@
1F419 ; fully-qualified # 🐙 E0.6 octopus
1F41A ; fully-qualified # 🐚 E0.6 spiral shell
1FAB8 ; fully-qualified # 🪸 E14.0 coral
+1FABC ; fully-qualified # 🪼 E15.0 jellyfish
# subgroup: animal-bug
1F40C ; fully-qualified # 🐌 E0.6 snail
@@ -3433,6 +3456,7 @@
1F33B ; fully-qualified # 🌻 E0.6 sunflower
1F33C ; fully-qualified # 🌼 E0.6 blossom
1F337 ; fully-qualified # 🌷 E0.6 tulip
+1FABB ; fully-qualified # 🪻 E15.0 hyacinth
# subgroup: plant-other
1F331 ; fully-qualified # 🌱 E0.6 seedling
@@ -3451,9 +3475,10 @@
1F343 ; fully-qualified # 🍃 E0.6 leaf fluttering in wind
1FAB9 ; fully-qualified # 🪹 E14.0 empty nest
1FABA ; fully-qualified # 🪺 E14.0 nest with eggs
+1F344 ; fully-qualified # 🍄 E0.6 mushroom
-# Animals & Nature subtotal: 151
-# Animals & Nature subtotal: 151 w/o modifiers
+# Animals & Nature subtotal: 159
+# Animals & Nature subtotal: 159 w/o modifiers
# group: Food & Drink
@@ -3492,10 +3517,11 @@
1F966 ; fully-qualified # 🥦 E5.0 broccoli
1F9C4 ; fully-qualified # 🧄 E12.0 garlic
1F9C5 ; fully-qualified # 🧅 E12.0 onion
-1F344 ; fully-qualified # 🍄 E0.6 mushroom
1F95C ; fully-qualified # 🥜 E3.0 peanuts
1FAD8 ; fully-qualified # 🫘 E14.0 beans
1F330 ; fully-qualified # 🌰 E0.6 chestnut
+1FADA ; fully-qualified # 🫚 E15.0 ginger root
+1FADB ; fully-qualified # 🫛 E15.0 pea pod
# subgroup: food-prepared
1F35E ; fully-qualified # 🍞 E0.6 bread
@@ -3607,8 +3633,8 @@
1FAD9 ; fully-qualified # 🫙 E14.0 jar
1F3FA ; fully-qualified # 🏺 E1.0 amphora
-# Food & Drink subtotal: 134
-# Food & Drink subtotal: 134 w/o modifiers
+# Food & Drink subtotal: 135
+# Food & Drink subtotal: 135 w/o modifiers
# group: Travel & Places
@@ -3974,11 +4000,10 @@
1F3AF ; fully-qualified # 🎯 E0.6 bullseye
1FA80 ; fully-qualified # 🪀 E12.0 yo-yo
1FA81 ; fully-qualified # 🪁 E12.0 kite
+1F52B ; fully-qualified # 🔫 E0.6 water pistol
1F3B1 ; fully-qualified # 🎱 E0.6 pool 8 ball
1F52E ; fully-qualified # 🔮 E0.6 crystal ball
1FA84 ; fully-qualified # 🪄 E13.0 magic wand
-1F9FF ; fully-qualified # 🧿 E11.0 nazar amulet
-1FAAC ; fully-qualified # 🪬 E14.0 hamsa
1F3AE ; fully-qualified # 🎮 E0.6 video game
1F579 FE0F ; fully-qualified # 🕹️ E0.7 joystick
1F579 ; unqualified # 🕹 E0.7 joystick
@@ -4013,8 +4038,8 @@
1F9F6 ; fully-qualified # 🧶 E11.0 yarn
1FAA2 ; fully-qualified # 🪢 E13.0 knot
-# Activities subtotal: 97
-# Activities subtotal: 97 w/o modifiers
+# Activities subtotal: 96
+# Activities subtotal: 96 w/o modifiers
# group: Objects
@@ -4040,6 +4065,7 @@
1FA73 ; fully-qualified # 🩳 E12.0 shorts
1F459 ; fully-qualified # 👙 E0.6 bikini
1F45A ; fully-qualified # 👚 E0.6 woman’s clothes
+1FAAD ; fully-qualified # 🪭 E15.0 folding hand fan
1F45B ; fully-qualified # 👛 E0.6 purse
1F45C ; fully-qualified # 👜 E0.6 handbag
1F45D ; fully-qualified # 👝 E0.6 clutch bag
@@ -4055,6 +4081,7 @@
1F461 ; fully-qualified # 👡 E0.6 woman’s sandal
1FA70 ; fully-qualified # 🩰 E12.0 ballet shoes
1F462 ; fully-qualified # 👢 E0.6 woman’s boot
+1FAAE ; fully-qualified # 🪮 E15.0 hair pick
1F451 ; fully-qualified # 👑 E0.6 crown
1F452 ; fully-qualified # 👒 E0.6 woman’s hat
1F3A9 ; fully-qualified # 🎩 E0.6 top hat
@@ -4103,6 +4130,8 @@
1FA95 ; fully-qualified # 🪕 E12.0 banjo
1F941 ; fully-qualified # 🥁 E3.0 drum
1FA98 ; fully-qualified # 🪘 E13.0 long drum
+1FA87 ; fully-qualified # 🪇 E15.0 maracas
+1FA88 ; fully-qualified # 🪈 E15.0 flute
# subgroup: phone
1F4F1 ; fully-qualified # 📱 E0.6 mobile phone
@@ -4275,7 +4304,7 @@
1F5E1 ; unqualified # 🗡 E0.7 dagger
2694 FE0F ; fully-qualified # ⚔️ E1.0 crossed swords
2694 ; unqualified # ⚔ E1.0 crossed swords
-1F52B ; fully-qualified # 🔫 E0.6 water pistol
+1F4A3 ; fully-qualified # 💣 E0.6 bomb
1FA83 ; fully-qualified # 🪃 E13.0 boomerang
1F3F9 ; fully-qualified # 🏹 E1.0 bow and arrow
1F6E1 FE0F ; fully-qualified # 🛡️ E0.7 shield
@@ -4354,12 +4383,14 @@
1FAA6 ; fully-qualified # 🪦 E13.0 headstone
26B1 FE0F ; fully-qualified # ⚱️ E1.0 funeral urn
26B1 ; unqualified # ⚱ E1.0 funeral urn
+1F9FF ; fully-qualified # 🧿 E11.0 nazar amulet
+1FAAC ; fully-qualified # 🪬 E14.0 hamsa
1F5FF ; fully-qualified # 🗿 E0.6 moai
1FAA7 ; fully-qualified # 🪧 E13.0 placard
1FAAA ; fully-qualified # 🪪 E14.0 identification card
-# Objects subtotal: 304
-# Objects subtotal: 304 w/o modifiers
+# Objects subtotal: 310
+# Objects subtotal: 310 w/o modifiers
# group: Symbols
@@ -4455,6 +4486,7 @@
262E ; unqualified # ☮ E1.0 peace symbol
1F54E ; fully-qualified # 🕎 E1.0 menorah
1F52F ; fully-qualified # 🔯 E0.6 dotted six-pointed star
+1FAAF ; fully-qualified # 🪯 E15.0 khanda
# subgroup: zodiac
2648 ; fully-qualified # ♈ E0.6 Aries
@@ -4503,6 +4535,7 @@
1F505 ; fully-qualified # 🔅 E1.0 dim button
1F506 ; fully-qualified # 🔆 E1.0 bright button
1F4F6 ; fully-qualified # 📶 E0.6 antenna bars
+1F6DC ; fully-qualified # 🛜 E15.0 wireless
1F4F3 ; fully-qualified # 📳 E0.6 vibration mode
1F4F4 ; fully-qualified # 📴 E0.6 mobile phone off
@@ -4693,8 +4726,8 @@
1F533 ; fully-qualified # 🔳 E0.6 white square button
1F532 ; fully-qualified # 🔲 E0.6 black square button
-# Symbols subtotal: 302
-# Symbols subtotal: 302 w/o modifiers
+# Symbols subtotal: 304
+# Symbols subtotal: 304 w/o modifiers
# group: Flags
@@ -4709,7 +4742,7 @@
1F3F3 200D 1F308 ; unqualified # 🏳‍🌈 E4.0 rainbow flag
1F3F3 FE0F 200D 26A7 FE0F ; fully-qualified # 🏳️‍⚧️ E13.0 transgender flag
1F3F3 200D 26A7 FE0F ; unqualified # 🏳‍⚧️ E13.0 transgender flag
-1F3F3 FE0F 200D 26A7 ; unqualified # 🏳️‍⚧ E13.0 transgender flag
+1F3F3 FE0F 200D 26A7 ; minimally-qualified # 🏳️‍⚧ E13.0 transgender flag
1F3F3 200D 26A7 ; unqualified # 🏳‍⚧ E13.0 transgender flag
1F3F4 200D 2620 FE0F ; fully-qualified # 🏴‍☠️ E11.0 pirate flag
1F3F4 200D 2620 ; minimally-qualified # 🏴‍☠ E11.0 pirate flag
@@ -4983,9 +5016,9 @@
# Flags subtotal: 275 w/o modifiers
# Status Counts
-# fully-qualified : 3624
-# minimally-qualified : 817
-# unqualified : 252
+# fully-qualified : 3655
+# minimally-qualified : 827
+# unqualified : 242
# component : 9
#EOF
diff --git a/admin/unidata/emoji-zwj-sequences.txt b/admin/unidata/emoji-zwj-sequences.txt
index 6f94721a73a..4125bec62e2 100644
--- a/admin/unidata/emoji-zwj-sequences.txt
+++ b/admin/unidata/emoji-zwj-sequences.txt
@@ -1,13 +1,13 @@
# emoji-zwj-sequences.txt
-# Date: 2021-06-08, 05:19:16 GMT
-# © 2021 Unicode®, Inc.
+# Date: 2022-05-06, 16:14:52 GMT
+# © 2022 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Emoji ZWJ Sequences for UTS #51
-# Version: 14.0
+# Version: 15.0
#
-# For documentation and usage, see http://www.unicode.org/reports/tr51
+# For documentation and usage, see https://www.unicode.org/reports/tr51
#
# Format:
# code_point(s) ; type_field ; description # comments
@@ -1398,6 +1398,7 @@
1F3F4 200D 2620 FE0F ; RGI_Emoji_ZWJ_Sequence ; pirate flag # E11.0 [1] (🏴‍☠️)
1F408 200D 2B1B ; RGI_Emoji_ZWJ_Sequence ; black cat # E13.0 [1] (🐈‍⬛)
1F415 200D 1F9BA ; RGI_Emoji_ZWJ_Sequence ; service dog # E12.0 [1] (🐕‍🦺)
+1F426 200D 2B1B ; RGI_Emoji_ZWJ_Sequence ; black bird # E15.0 [1] (🐦‍⬛)
1F43B 200D 2744 FE0F ; RGI_Emoji_ZWJ_Sequence ; polar bear # E13.0 [1] (🐻‍❄️)
1F441 FE0F 200D 1F5E8 FE0F ; RGI_Emoji_ZWJ_Sequence ; eye in speech bubble # E2.0 [1] (👁️‍🗨️)
1F62E 200D 1F4A8 ; RGI_Emoji_ZWJ_Sequence ; face exhaling # E13.1 [1] (😮‍💨)
@@ -1405,6 +1406,6 @@
1F636 200D 1F32B FE0F ; RGI_Emoji_ZWJ_Sequence ; face in clouds # E13.1 [1] (😶‍🌫️)
1F9D1 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus # E13.0 [1] (🧑‍🎄)
-# Total elements: 13
+# Total elements: 14
#EOF
diff --git a/admin/unidata/unidata-gen.el b/admin/unidata/unidata-gen.el
index 78dd1c37288..5927760ad58 100644
--- a/admin/unidata/unidata-gen.el
+++ b/admin/unidata/unidata-gen.el
@@ -212,12 +212,12 @@ Property value is one of the following symbols:
;; Character Database (UCD).
(L (#x0600 #x07BF AL) (#x0860 #x08FF AL) (#xFB50 #xFDCF AL)
(#xFDF0 #xFDFF AL) (#xFE70 #xFEFF AL) (#x10D00 #x10D3F AL)
- (#x10F30 #x10F6F AL) (#x1EC70 #x1ECBF AL) (#x1ED00 #x1ED4F AL)
- (#x1EE00 #x1EEFF AL)
+ (#x10EC0 #x10EFF AL) (#x10F30 #x10F6F AL) (#x1EC70 #x1ECBF AL)
+ (#x1ED00 #x1ED4F AL) (#x1EE00 #x1EEFF AL)
(#x0590 #x05FF R) (#x07C0 #x085F R) (#xFB1D #xFB4F R)
- (#x10800 #x10CFF R) (#x10D40 #x10F2F R) (#x10F70 #x10FFF R)
- (#x1E800 #x1EC6F R) (#x1ECC0 #x1ECFF R) (#x1ED50 #x1EDFF R)
- (#x1EF00 #x1EFFF R)
+ (#x10800 #x10CFF R) (#x10D40 #x10EBF R) (#x10F00 #x10F2F R)
+ (#x10F70 #x10FFF R) (#x1E800 #x1EC6F R) (#x1ECC0 #x1ECFF R)
+ (#x1ED50 #x1EDFF R) (#x1EF00 #x1EFFF R)
(#x20A0 #x20CF ET))
;; The order of elements must be in sync with bidi_type_t in
;; src/dispextern.h.
diff --git a/admin/update-copyright b/admin/update-copyright
index 5a04847a661..8b7c05749d0 100755
--- a/admin/update-copyright
+++ b/admin/update-copyright
@@ -31,6 +31,8 @@
# updated and some should not be, due to registration numbers, so
# this script leaves these copyright years alone for now.
+set -o nounset
+
: ${UPDATE_COPYRIGHT_USE_INTERVALS=1}
export UPDATE_COPYRIGHT_USE_INTERVALS
diff --git a/admin/update_autogen b/admin/update_autogen
index 24513671712..d1f49d9f25e 100755
--- a/admin/update_autogen
+++ b/admin/update_autogen
@@ -32,6 +32,8 @@
### Code:
+set -o nounset
+
die () # write error to stderr and exit
{
[ $# -gt 0 ] && echo "$PN: $@" >&2
@@ -93,6 +95,7 @@ genfiles="
## msdos-only:
genfiles="src/config.in"
+basegen=""
for g in $genfiles; do
basegen="$basegen ${g##*/}"
done
@@ -144,6 +147,7 @@ status ()
local stat file modified
+ modified=""
while read stat file; do
[ "$stat" != "M" ] && \
diff --git a/admin/upload-manuals b/admin/upload-manuals
index 1b7950ede80..50336ee64c0 100755
--- a/admin/upload-manuals
+++ b/admin/upload-manuals
@@ -36,6 +36,7 @@
### Code:
+set -o nounset
die () # write error to stderr and exit
{
diff --git a/build-aux/config.guess b/build-aux/config.guess
index 1817bdce90d..a419d8643b6 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -4,7 +4,7 @@
# shellcheck disable=SC2006,SC2268 # see below for rationale
-timestamp='2022-05-25'
+timestamp='2022-08-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -1036,7 +1036,7 @@ EOF
k1om:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
- loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
+ loongarch32:Linux:*:* | loongarch64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
m32r*:Linux:*:*)
diff --git a/build-aux/config.sub b/build-aux/config.sub
index dba16e84c77..fbaa37f2352 100755
--- a/build-aux/config.sub
+++ b/build-aux/config.sub
@@ -4,7 +4,7 @@
# shellcheck disable=SC2006,SC2268 # see below for rationale
-timestamp='2022-01-03'
+timestamp='2022-08-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -1207,7 +1207,7 @@ case $cpu-$vendor in
| k1om \
| le32 | le64 \
| lm32 \
- | loongarch32 | loongarch64 | loongarchx32 \
+ | loongarch32 | loongarch64 \
| m32c | m32r | m32rle \
| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
diff --git a/config.bat b/config.bat
index 4adc477bc95..7f2060ce000 100644
--- a/config.bat
+++ b/config.bat
@@ -276,6 +276,7 @@ cd lib
Rem Rename files like djtar on plain DOS filesystem would.
If Exist c++defs.h update c++defs.h cxxdefs.h
If Exist alloca.in.h update alloca.in.h alloca.in-h
+If Exist assert.in.h update assert.in.h assert.in-h
If Exist byteswap.in.h update byteswap.in.h byteswap.in-h
If Exist dirent.in.h update dirent.in.h dirent.in-h
If Exist errno.in.h update errno.in.h errno.in-h
diff --git a/configure.ac b/configure.ac
index 4590ed3506e..2d843440503 100644
--- a/configure.ac
+++ b/configure.ac
@@ -494,7 +494,6 @@ OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support])
OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support])
OPTION_DEFAULT_ON([modules],[don't compile with dynamic modules support])
OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support])
-OPTION_DEFAULT_OFF([native-compilation],[compile with Emacs Lisp native compiler support])
OPTION_DEFAULT_OFF([cygwin32-native-compilation],[use native compilation on 32-bit Cygwin])
OPTION_DEFAULT_ON([xinput2],[don't use version 2 of the X Input Extension for input])
OPTION_DEFAULT_OFF([small-ja-dic],[generate a smaller-size Japanese dictionary])
@@ -1009,6 +1008,29 @@ AC_ARG_ENABLE([gcc-warnings],
[gl_GCC_VERSION_IFELSE([5], [3], [gl_gcc_warnings=warn-only])])
fi])
+NATIVE_COMPILATION_AOT=no
+AC_ARG_WITH([native-compilation],
+ [AS_HELP_STRING([--with-native-compilation@<:@=TYPE@:>@],
+ [compile with Emacs Lisp native compiler support. The TYPE
+ 'yes' (or empty) means to enable it and compile natively
+ preloaded Lisp files; 'no' means to disable it;
+ 'aot' will make the build process compile all the Lisp
+ files in the tree natively ahead of time. (This will
+ usually be quite slow.)])],
+ [
+ case $withval in
+ aot)
+ withval=yes
+ NATIVE_COMPILATION_AOT=yes
+ ;;
+ yes|no) ;;
+ *) AC_MSG_ERROR([bad value $withval for native-compilation option]) ;;
+ esac
+ with_native_compilation=$withval],
+ [with_native_compilation=no]
+)
+AC_SUBST([NATIVE_COMPILATION_AOT])
+
AC_ARG_ENABLE([check-lisp-object-type],
[AS_HELP_STRING([--enable-check-lisp-object-type],
[Enable compile time checks for the Lisp_Object data type,
diff --git a/doc/emacs/ack.texi b/doc/emacs/ack.texi
index 52ce8a16e6e..f0a45fd3151 100644
--- a/doc/emacs/ack.texi
+++ b/doc/emacs/ack.texi
@@ -524,8 +524,9 @@ Denis Howe wrote @file{browse-url.el}, a package for invoking a WWW
browser to display a URL.
@item
-Lars Magne Ingebrigtsen did a major redesign of the Gnus news-reader and
-wrote many of its parts. Several of these are now general components of
+Lars Magne Ingebrigtsen was the Emacs (co-)maintainer from Emacs 27.2
+onwards. He did a major redesign of the Gnus news-reader and wrote
+many of its parts. Several of these are now general components of
Emacs, including: @file{dns.el} for Domain Name Service lookups;
@file{format-spec.el} for formatting arbitrary format strings;
@file{netrc.el} for parsing of @file{.netrc} files; and
@@ -1440,7 +1441,8 @@ Victor Zandy wrote @file{zone.el}, a package for people who like to
zone out in front of Emacs.
@item
-Eli Zaretskii made many standard Emacs features work on MS-DOS and
+Eli Zaretskii was the Emacs (co-)maintainer from Emacs 25
+onwards. He made many standard Emacs features work on MS-DOS and
Microsoft Windows. He also wrote @file{tty-colors.el}, which
implements transparent mapping of X colors to tty colors; and
@file{rxvt.el}. He implemented support for bidirectional text, menus
diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi
index 120c957ff86..8b21b6457cd 100644
--- a/doc/emacs/buffers.texi
+++ b/doc/emacs/buffers.texi
@@ -631,13 +631,11 @@ buffer, but killing an indirect buffer has no effect on its base buffer.
outline. @xref{Outline Views}.
A quick and handy way to make an indirect buffer is with the command
-@kbd{M-x clone-indirect-buffer}. It creates and selects an indirect
-buffer whose base buffer is the current buffer. With a numeric
-argument, it prompts for the name of the indirect buffer; otherwise it
-uses the name of the current buffer, with a @samp{<@var{n}>} suffix
-added. @kbd{C-x 4 c} (@code{clone-indirect-buffer-other-window})
-works like @kbd{M-x clone-indirect-buffer}, but it selects the new
-buffer in another window.
+@kbd{C-x 4 c} (@code{clone-indirect-buffer-other-window}). It creates
+and selects an indirect buffer whose base buffer is the current
+buffer. With a numeric argument, it prompts for the name of the
+indirect buffer; otherwise it uses the name of the current buffer,
+with a @samp{<@var{n}>} suffix added.
The more general way to make an indirect buffer is with the command
@kbd{M-x make-indirect-buffer}. It creates an indirect buffer
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index ff7ab83190c..f98527bf9a7 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -667,6 +667,16 @@ type @kbd{M-x disable-theme}.
the @file{*Custom Themes*} buffer; or type @kbd{M-x describe-theme}
anywhere in Emacs and enter the theme name.
+@findex theme-choose-variant
+Some themes have variants (most often just two: light and dark). You
+can switch to another variant using @kbd{M-x theme-choose-variant}.
+If the currently active theme has only one other variant, it will be
+selected; if there are more variants, the command will prompt you
+which one to switch to.
+
+Note that @code{theme-choose-variant} only works if a single theme
+is active.
+
@node Creating Custom Themes
@subsection Creating Custom Themes
@cindex custom themes, creating
diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 33e9270d42d..a9b4ff783d4 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -1641,7 +1641,7 @@ or through an external viewer. This is different from Image mode
To enter Image-Dired, mark the image files you want to look at in
the Dired buffer, using @kbd{m} as usual. Then type @kbd{C-t d}
(@code{image-dired-display-thumbs}). This creates and switches to a
-buffer containing image-dired, corresponding to the marked files.
+buffer containing Image-Dired, corresponding to the marked files.
You can also enter Image-Dired directly by typing @kbd{M-x
image-dired}. This prompts for a directory; specify one that has
@@ -1650,20 +1650,21 @@ directory, and displays them all in the thumbnail buffer. The
thumbnails are generated in the background and are loaded as they
become available.
+@findex image-dired-display-this
+@findex image-dired-display-next
+@findex image-dired-display-previous
With point in the thumbnail buffer, you can type @key{RET}
-(@code{image-dired-display-thumbnail-original-image}) to display the
-image in another window. Use the arrow keys to move around in the
-thumbnail buffer. For easy browsing, use @key{SPC}
-(@code{image-dired-display-next-thumbnail-original}) to advance and
-display the next image. Typing @key{DEL}
-(@code{image-dired-display-previous-thumbnail-original}) backs up to
-the previous thumbnail and displays that instead.
+(@code{image-dired-display-this}) to display the image in another
+window. Use the arrow keys to move around in the thumbnail buffer.
+For easy browsing, use @key{SPC} (@code{image-dired-display-next}) to
+advance and display the next image. Typing @key{DEL}
+(@code{image-dired-display-previous}) backs up to the previous
+thumbnail and displays that instead.
@vindex image-dired-external-viewer
- To view the image in its original size, either provide a prefix
-argument (@kbd{C-u}) before pressing @key{RET}, or type
-@kbd{C-@key{RET}} (@code{image-dired-thumbnail-display-external}) to
-display the image in an external viewer. You must first configure
+ Type @kbd{C-@key{RET}}
+(@code{image-dired-thumbnail-display-external}) to display the image
+in an external viewer. You must first configure
@code{image-dired-external-viewer}.
You can delete images through Image-Dired also. Type @kbd{d}
@@ -1674,9 +1675,9 @@ image from the thumbnail buffer with @kbd{C-d}
More advanced features include @dfn{image tags}, which are metadata
used to categorize image files. The tags are stored in a plain text
-file configured by @code{image-dired-db-file}.
+file configured by @code{image-dired-tags-db-file}.
- To tag image files, mark them in the dired buffer (you can also mark
+ To tag image files, mark them in the Dired buffer (you can also mark
files in Dired from the thumbnail buffer by typing @kbd{m}) and type
@kbd{C-t t} (@code{image-dired-tag-files}). This reads the tag name
in the minibuffer. To mark files having a certain tag, type @kbd{C-t f}
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index 6206dee4850..727f5f93bff 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -853,6 +853,7 @@ Miscellaneous Commands and Features of VC
* VC Delete/Rename:: Deleting and renaming version-controlled files.
* Revision Tags:: Symbolic names for revisions.
* Version Headers:: Inserting version control headers into working files.
+* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
Customizing VC
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index 5b3b15cd38f..1717c5c25bc 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -2270,17 +2270,20 @@ behavior by using the options @code{image-auto-resize} and
@code{image-auto-resize-on-window-resize}.
@findex image-transform-fit-to-window
+@findex image-transform-set-percent
@findex image-transform-set-scale
-@findex image-transform-reset
+@findex image-transform-reset-to-initial
+@findex image-transform-reset-to-original
To resize the image manually you can use the command
@code{image-transform-fit-to-window} bound to @kbd{s w} that fits the
image to both the window height and width. To scale the image to a
percentage of its original size, use the command
-@code{image-transform-set-percent} bound to @kbd{s p}. To scale
-the image specifying a scale factor, use the command
+@code{image-transform-set-percent} bound to @kbd{s p}. To scale the
+image specifying a scale factor, use the command
@code{image-transform-set-scale} bound to @kbd{s s}. To reset all
-transformations to the initial state, use @code{image-transform-reset}
-bound to @kbd{s 0}.
+transformations to the initial state, use
+@code{image-transform-reset-to-initial} bound to @kbd{s 0}, or
+@code{image-transform-reset-to-original} bound to @kbd{s o}.
@findex image-next-file
@findex image-previous-file
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi
index 8a255fa40fb..3ff47c6ffcf 100644
--- a/doc/emacs/frames.texi
+++ b/doc/emacs/frames.texi
@@ -652,14 +652,15 @@ resources file to take effect. @xref{Resources}. Do not quote
font names in X resource files.
@item
-If you are running Emacs on the GNOME desktop, you can tell Emacs to
-use the default system font by setting the variable
+If you are running Emacs on the GNOME desktop or Haiku, you can tell
+Emacs to adjust the frame's default font along with changes to the
+default system font by setting the variable
@code{font-use-system-font} to @code{t} (the default is @code{nil}).
For this to work, Emacs must have been compiled with support for
Gsettings (or the older Gconf). (To be specific, the Gsettings
-configuration names used are
-@samp{org.gnome.desktop.interface monospace-font-name} and
-@samp{org.gnome.desktop.interface font-name}.)
+configuration names used are @samp{org.gnome.desktop.interface
+monospace-font-name} and @samp{org.gnome.desktop.interface
+font-name}.)
@item
Use the command line option @samp{-fn} (or @samp{--font}). @xref{Font
diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index 84b082825c2..6d9c028b742 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -311,12 +311,11 @@ doc string to display. In that case, if
to load the file in which the function is defined to see whether
there's a doc string there.
-@findex shortdoc-display-group
+@findex shortdoc
You can get an overview of functions relevant for a particular topic
-by using the @kbd{M-x shortdoc-display-group} command. This will
-prompt you for an area of interest, e.g., @code{string}, and pop you
-to a buffer where many of the functions relevant for handling strings
-are listed.
+by using the @kbd{M-x shortdoc} command. This will prompt you for an
+area of interest, e.g., @code{string}, and pop you to a buffer where
+many of the functions relevant for handling strings are listed.
@kindex C-h v
@findex describe-variable
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 89e6b2215c9..ad4a3ea3506 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -901,7 +901,14 @@ is non-@code{nil}, the colors expressing the age of each line are
applied to the background color, leaving the foreground at its default
color.
- When you give a prefix argument to this command, Emacs reads two
+@vindex vc-annotate-switches
+ You can customize the @code{annotate} options that @kbd{C-x v g}
+uses by customizing @code{vc-@var{backend}-annotate-switches} and
+@code{vc-annotate-switches}. They function similarly to
+@code{vc-@var{backend}-diff-switches} and @code{vc-diff-switches},
+described above.
+
+ When you give a prefix argument to @kbd{C-x v g}, Emacs reads two
arguments using the minibuffer: the revision to display and annotate
(instead of the current file contents), and the time span in days the
color range should cover.
@@ -1034,13 +1041,14 @@ revision at point. A second @key{RET} hides it again.
(@code{vc-log-incoming}) command displays a log buffer showing the
changes that will be applied, the next time you run the version
control system's pull command to get new revisions from another
-repository (@pxref{Pulling / Pushing}). This other repository is the default
+remote location (@pxref{Pulling / Pushing}). This other remote location is the default
one from which changes are pulled, as defined by the version control
system; with a prefix argument, @code{vc-log-incoming} prompts for a
-specific repository. Similarly, @kbd{C-x v O}
+specific remote location. Similarly, @kbd{C-x v O}
(@code{vc-log-outgoing}) shows the changes that will be sent to
-another repository, the next time you run the push command; with a
-prefix argument, it prompts for a specific destination repository.
+another remote location, the next time you run the push command; with a
+prefix argument, it prompts for a specific destination that
+in case of some version control system can be a branch name.
@cindex VC log buffer, commands in
@cindex vc-log buffer
@@ -2294,7 +2302,9 @@ Display the reference on the current line in the other window
@item r @var{pattern} @key{RET} @var{replacement} @key{RET}
Perform interactive query-replace on references that match
@var{pattern} (@code{xref-query-replace-in-results}), replacing
-the match with @var{replacement}. @xref{Identifier Search}.
+the match with @var{replacement}. This command can only be used in
+@file{*xref*} buffers that show all the matches for an identifier in
+all the relevant files. @xref{Identifier Search}.
@item g
@findex xref-revert-buffer
@@ -2328,7 +2338,8 @@ them.
@item M-?
Find all the references for the identifier at point.
-@item M-x xref-query-replace-in-results @key{RET} @var{replacement} @key{RET}
+@item r
+@itemx M-x xref-query-replace-in-results @key{RET} @var{replacement} @key{RET}
@itemx C-u M-x xref-query-replace-in-results @key{RET} @var{regexp} @key{RET} @var{replacement} @key{RET}
Interactively replace @var{regexp} with @var{replacement} in the names
of all the identifiers shown in the @file{*xref*} buffer.
@@ -2374,16 +2385,18 @@ shown. The default value is @code{nil}, which just shows the results
in the @file{*xref*} buffer, but doesn't select any of them.
@findex xref-query-replace-in-results
- @kbd{M-x xref-query-replace-in-results} reads a @var{replacement}
+ @kbd{r} (@code{xref-query-replace-in-results}) reads a @var{replacement}
string, just like ordinary @kbd{M-x query-replace-regexp}. It then
renames the identifiers shown in the @file{*xref*} buffer in all the
places in all the files where these identifiers are referenced, such
that their new name is @var{replacement}. This is useful when you
rename your identifiers as part of refactoring. This command should
-be invoked in the @file{*xref*} buffer generated by @kbd{M-?}. With a
-prefix argument, the command also prompts for a regexp to match
-identifier names, and renames that regexp in the names of the matching
-identifiers with @var{replacement}.
+be invoked in the @file{*xref*} buffer generated by @kbd{M-?}. By
+default, the command replaces the entire name of each identifier with
+@var{replacement}, but if invoked with a prefix argument, the command
+prompts for a regexp to match identifier names, and replaces only the
+matches of that regexp in the names of the identifiers with
+@var{replacement}.
@findex xref-find-references-and-replace
@kbd{M-x xref-find-references-and-replace} works similarly to
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 10b44028bb9..1514e316f8c 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -162,12 +162,12 @@ List killed groups (@code{gnus-group-list-killed}).
List zombie groups (@code{gnus-group-list-zombies}).
@kindex u @r{(Gnus Group mode)}
-@findex gnus-group-toggle-subscription
+@findex gnus-group-toggle-subscription-at-point
@cindex subscribe groups
@cindex unsubscribe groups
@item u
Toggle the subscription status of the group
-(@code{gnus-group-toggle-subscription}) on the current line.
+(@code{gnus-group-toggle-subscription-at-point}) on the current line.
Invoking this on a killed or zombie group turns it into an
unsubscribed group.
@@ -245,7 +245,7 @@ buffer and typed @kbd{C-s} (@pxref{Incremental Search}).
@kindex M-s M-s @r{(Gnus Summary mode)}
@findex gnus-summary-search-article-forward
-@item M-s @var{regexp} @key{RET}
+@item M-s M-s @var{regexp} @key{RET}
Search forward for articles containing a match for @var{regexp}
(@code{gnus-summary-search-article-forward}).
@@ -584,6 +584,18 @@ you instead want the image to be re-rendered at the new size, set
default size for DocView, customize the variable
@code{doc-view-resolution}.
+@vindex doc-view-imenu-enabled
+@vindex doc-view-imenu-flatten
+@vindex doc-view-imenu-format
+ When the @command{mutool} program is available, DocView will use it
+to generate entries for an outline menu, making it accessible via the
+@code{imenu} facility (@pxref{Imenu}). To disable this functionality
+even when @command{mutool} can be found on your system, customize the
+variable @code{doc-view-imenu-enabled} to the @code{nil} value. You
+can further customize how @code{imenu} items are formatted and
+displayed using the variables @code{doc-view-imenu-format} and
+@code{doc-view-flatten}.
+
@node DocView Searching
@subsection DocView Searching
diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi
index c348130807c..56b779f8de6 100644
--- a/doc/emacs/modes.texi
+++ b/doc/emacs/modes.texi
@@ -454,6 +454,13 @@ only @emph{after} @code{auto-mode-alist}. By default,
files, HTML/XML/SGML files, PostScript files, and Unix style Conf
files.
+@vindex major-mode-remap-alist
+ Once a major mode is found, Emacs does a final check to see if the
+mode has been remapped by @code{major-mode-remap-alist}, in which case
+it uses the remapped mode instead. This is used when several
+different major modes can be used for the same file type, so you can
+specify which mode you prefer.
+
@findex normal-mode
If you have changed the major mode of a buffer, you can return to
the major mode Emacs would have chosen automatically, by typing
diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi
index 5f303418383..1bbd7440f3e 100644
--- a/doc/emacs/mule.texi
+++ b/doc/emacs/mule.texi
@@ -61,7 +61,7 @@ can also be input by using the @kbd{C-x 8} prefix, see @ref{Unibyte Mode}.
With the X Window System, your locale should be set to an appropriate
value to make sure Emacs interprets keyboard input correctly; see
-@ref{Language Environments, locales}.
+@ref{Language Environments, locales}, and @ref{X Coding}.
@end itemize
The rest of this chapter describes these issues in detail.
@@ -79,6 +79,7 @@ value to make sure Emacs interprets keyboard input correctly; see
* Text Coding:: Choosing conversion to use for file text.
* Communication Coding:: Coding systems for interprocess communication.
* File Name Coding:: Coding systems for file @emph{names}.
+* X Coding:: Coding systems for X input methods.
* Terminal Coding:: Specifying coding systems for converting
terminal input and output.
* Fontsets:: Fontsets are collections of fonts
@@ -1241,15 +1242,14 @@ current language environment.
The variable @code{locale-coding-system} specifies a coding system
to use when encoding and decoding system strings such as system error
messages and @code{format-time-string} formats and time stamps. That
-coding system is also used for decoding non-@acronym{ASCII} keyboard
-input on the X Window System and for encoding text sent to the
-standard output and error streams when in batch mode. You should
-choose a coding system that is compatible
-with the underlying system's text representation, which is normally
-specified by one of the environment variables @env{LC_ALL},
-@env{LC_CTYPE}, and @env{LANG}. (The first one, in the order
-specified above, whose value is nonempty is the one that determines
-the text representation.)
+coding system might also be used for decoding non-@acronym{ASCII}
+keyboard input on the X Window System and will also be used to encode
+text sent to the standard output and error streams in batch mode. You
+should choose a coding system that is compatible with the underlying
+system's text representation, which is normally specified by one of
+the environment variables @env{LC_ALL}, @env{LC_CTYPE}, and
+@env{LANG}. (The first one, in the order specified above, whose value
+is nonempty is the one that determines the text representation.)
@node File Name Coding
@section Coding Systems for File Names
@@ -1311,6 +1311,26 @@ C-w} to specify a new file name for that buffer.
system. This prompts for an existing file name, its old coding
system, and the coding system to which you wish to convert.
+@node X Coding
+@section Coding Systems for X Keyboard Input
+@cindex X input method coding systems
+ Input methods under the X Window System specify their own coding
+systems that must be used to decode keyboard input. By default, Emacs
+determines the coding system used for each input method automatically
+upon establishing the connection to the input method server, and uses
+that specific coding system to decode keyboard input. However, that
+determination can sometimes fail; in that situation, the locale coding
+system (@pxref{Communication Coding}) is used instead.
+
+@cindex X input method coding systems, overriding
+@vindex x-input-coding-system
+ If the input method does not correctly announce the coding system it
+uses to encode text, then the coding system used by Emacs to decode
+text from input methods must be manually specified. The value of the
+variable @code{x-input-coding-system}, when set to a symbol, is
+unconditionally used as the coding system used to decode keyboard
+input from input methods.
+
@node Terminal Coding
@section Coding Systems for Terminal I/O
diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi
index 7e16c82cf5c..420da090977 100644
--- a/doc/emacs/package.texi
+++ b/doc/emacs/package.texi
@@ -421,13 +421,13 @@ lower-priority archives will not be shown in the menu, if the same
package is available from a higher-priority archive. (This is
controlled by the value of @code{package-menu-hide-low-priority}.)
- Once a package is downloaded and installed, it is made available to
-the current Emacs session. Making a package available adds its
-directory to @code{load-path} and loads its autoloads. The effect of
-a package's autoloads varies from package to package. Most packages
-just make some new commands available, while others have more
-wide-ranging effects on the Emacs session. For such information,
-consult the package's help buffer.
+ Once a package is downloaded, byte-compiled and installed, it is
+made available to the current Emacs session. Making a package
+available adds its directory to @code{load-path} and loads its
+autoloads. The effect of a package's autoloads varies from package to
+package. Most packages just make some new commands available, while
+others have more wide-ranging effects on the Emacs session. For such
+information, consult the package's help buffer.
Installed packages are automatically made available by Emacs in all
subsequent sessions. This happens at startup, before processing the
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index b87c659483a..30c7f106e50 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -508,9 +508,9 @@ Reindent each line in the balanced expression that follows point
about invalid syntax.
@item @key{TAB}
-@findex c-indent-command
-Reindent the current line, and/or in some cases insert a tab character
-(@code{c-indent-command}).
+@findex c-indent-line-or-region
+Reindent the current line, active region, or block starting on this
+line (@code{c-indent-line-or-region}).
@vindex c-tab-always-indent
If @code{c-tab-always-indent} is @code{t}, this command always reindents
@@ -985,7 +985,7 @@ Set comment column (@code{comment-set-column}).
@item @kbd{C-M-j}
@itemx @kbd{M-j}
Like @kbd{@key{RET}} followed by inserting and aligning a comment
-(@code{comment-indent-new-line}). @xref{Multi-Line Comments}.
+(@code{default-indent-new-line}). @xref{Multi-Line Comments}.
@item @kbd{M-x comment-region}
@itemx @kbd{C-c C-c} (in C-like modes)
Add comment delimiters to all the lines in the region.
@@ -1080,10 +1080,10 @@ the brace rather than at @code{comment-column}. For full details see
@kindex C-M-j
@kindex M-j
@cindex blank lines in programs
-@findex comment-indent-new-line
+@findex default-indent-new-line
@vindex comment-multi-line
If you are typing a comment and wish to continue it to another line,
-type @kbd{M-j} or @kbd{C-M-j} (@code{comment-indent-new-line}). This
+type @kbd{M-j} or @kbd{C-M-j} (@code{default-indent-new-line}). This
breaks the current line, and inserts the necessary comment delimiters
and indentation to continue the comment.
@@ -1331,8 +1331,8 @@ This abnormal hook holds documentation functions. It acts as a
collection of backends for ElDoc. This is what modes should use to
register their documentation functions with ElDoc.
-@vindex eldoc-display-truncation-message
-@item eldoc-display-truncation-message
+@vindex eldoc-echo-area-display-truncation-message
+@item eldoc-echo-area-display-truncation-message
If non-@code{nil} (the default), display a verbose message about how
to view a complete documentation (if it has been truncated in the echo
area). If @code{nil}, just mark truncated messages with @samp{...}.
@@ -1365,7 +1365,7 @@ count as blocks.
@findex hs-show-region
@findex hs-hide-level
@findex hs-toggle-hiding
-@findex hs-mouse-toggle-hiding
+@findex hs-toggle-hiding
@kindex C-c @@ C-h
@kindex C-c @@ C-s
@kindex C-c @@ C-c
@@ -1382,9 +1382,8 @@ Hide the current block (@code{hs-hide-block}).
Show the current block (@code{hs-show-block}).
@item C-c @@ C-c
@itemx C-c @@ C-e
+@itemx S-mouse-2
Either hide or show the current block (@code{hs-toggle-hiding}).
-@item S-mouse-2
-Toggle hiding for the block you click on (@code{hs-mouse-toggle-hiding}).
@item C-c @@ C-M-h
@itemx C-c @@ C-t
Hide all top-level blocks (@code{hs-hide-all}).
diff --git a/doc/emacs/regs.texi b/doc/emacs/regs.texi
index fb936018798..ef9187bb9a6 100644
--- a/doc/emacs/regs.texi
+++ b/doc/emacs/regs.texi
@@ -381,7 +381,8 @@ jump to the bookmark.
@code{bookmark-jump} can find the proper position even if the file is
modified slightly. The variable @code{bookmark-search-size} says how
many characters of context to record on each side of the bookmark's
-position.
+position. (In buffers that are visiting encrypted files, no context
+is saved in the bookmarks file no matter the value of this variable.)
Here are some additional commands for working with bookmarks:
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index fa8eaf09245..b103e22e392 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -1003,6 +1003,11 @@ addition to ellipsis to show that a section is hidden. Using
@kbd{RET} (or clicking on the button with a mouse) will toggle
displaying the section.
+@vindex outline-minor-mode-use-margins
+ If @code{outline-minor-mode-use-margins} is non-@code{nil}, Outline
+minor mode will use the window margins in addition to ellipsis to show
+that a section is hidden.
+
@vindex outline-minor-mode-cycle
If the @code{outline-minor-mode-cycle} user option is
non-@code{nil}, the @kbd{TAB} and @kbd{S-@key{TAB}} keys are enabled on the
@@ -1509,15 +1514,15 @@ etc.
@subsection Org as an authoring system
@cindex Org exporting
-@findex org-export
+@findex org-export-dispatch
@kindex C-c C-e @r{(Org mode)}
You may want to format your Org notes nicely and to prepare them for
export and publication. To export the current buffer, type @kbd{C-c
-C-e} (@code{org-export}) anywhere in an Org buffer. This command
-prompts for an export format; currently supported formats include
-HTML, @LaTeX{}, Texinfo, OpenDocument (@file{.odt}), iCalendar,
-Markdown, man-page, and PDF@. Some formats, such as PDF, require
-certain system tools to be installed.
+C-e} (@code{org-export-dispatch}) anywhere in an Org buffer. This
+command prompts for an export format; currently supported formats
+include HTML, @LaTeX{}, Texinfo, OpenDocument (@file{.odt}),
+iCalendar, Markdown, man-page, and PDF@. Some formats, such as PDF,
+require certain system tools to be installed.
@vindex org-publish-project-alist
To export several files at once to a specific directory, either
diff --git a/doc/emacs/vc1-xtra.texi b/doc/emacs/vc1-xtra.texi
index 3ccad507159..23d5f504322 100644
--- a/doc/emacs/vc1-xtra.texi
+++ b/doc/emacs/vc1-xtra.texi
@@ -15,6 +15,8 @@
* VC Delete/Rename:: Deleting and renaming version-controlled files.
* Revision Tags:: Symbolic names for revisions.
* Version Headers:: Inserting version control headers into working files.
+* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
+* Preparing Patches:: Preparing and Composing patches from within VC
@end menu
@node Change Logs and VC
@@ -263,6 +265,55 @@ elements of the form @code{(@var{regexp} . @var{format})}. Whenever
part of the version header. A @samp{%s} in @var{format} is replaced
with the file's version control type.
+@node Editing VC Commands
+@subsubsection Editing VC Commands
+
+@findex vc-edit-next-command
+@kindex C-x v !
+You can use the @kbd{C-x v !} (@code{vc-edit-next-command}) prefix
+command to edit the shell command line that VC is about to run. This
+is primarily intended to make it possible to add optional command-line
+arguments to VCS commands without unnecessary complications of the VC
+command set and its interfaces with the backend.
+
+For example, Git can produce logs of more than one branch, but
+@kbd{C-x v b l} (@code{vc-print-branch-log}) prompts for the name of
+just one branch. To obtain a log of more than one branch, you can
+type @w{@kbd{C-x v ! C-x v b l}} and then append the names of
+additional branches to the end of the @samp{git log} command that VC
+is about to run.
+
+@node Preparing Patches
+@subsubsection Preparing Patches
+
+@findex vc-prepare-patch
+When collaborating on projects it is common to send patches via email,
+to share changes. If you wish to do this using VC, you can use the
+@code{vc-prepare-patch} command. This will prompt you for the
+revisions you wish to share, and which destination email address(es)
+to use. The revisions are separated using commas (or whatever was
+configured by @var{crm-separator}). The command will then prepare
+those revisions using your @abbr{MUA, Mail User Agent} for you to
+review and send.
+
+When invoked interactively in a Log View buffer with marked revisions,
+these revisions will be used.
+
+@vindex vc-prepare-patches-separately
+Depending on the value of the user option
+@code{vc-prepare-patches-separately}, @code{vc-prepare-patch} will
+generate one or more messages. The default value @code{t} means
+prepare and display a message for each revision, one after another. A
+value of @code{nil} means to generate a single message with all
+patches attached in the body.
+
+@vindex vc-default-patch-addressee
+If you expect to contribute patches on a regular basis, you can set
+the user option @code{vc-default-patch-addressee} to the address(es)
+you wish to use. This will be used as the default value when invoking
+@code{vc-prepare-patch}. Project maintainers may consider setting
+this as a directory local variable (@pxref{Directory Variables}).
+
@node Customizing VC
@subsection Customizing VC
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 47a5a870fde..df8fa2f8e79 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -10100,9 +10100,8 @@ resources; as it happens, methods that people find easy---that are
frugal of mental resources---sometimes use considerable computer
resources. Emacs was designed to run on machines that we now consider
limited and its default settings are conservative. You may want to
-increase the values of @code{max-specpdl-size} and
-@code{max-lisp-eval-depth}. In my @file{.emacs} file, I set them to
-15 and 30 times their default value.}.
+increase the value of @code{max-lisp-eval-depth}. In my @file{.emacs}
+file, I set it to 30 times its default value.}.
@menu
* while:: Causing a stretch of code to repeat.
diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi
index 6a1d125701c..c40e088293e 100644
--- a/doc/lispref/buffers.texi
+++ b/doc/lispref/buffers.texi
@@ -427,19 +427,19 @@ It is a permanent local, unaffected by
@end defvar
@defvar buffer-file-number
-This buffer-local variable holds the file number and directory device
-number of the file visited in the current buffer, or @code{nil} if no
+This buffer-local variable holds the inode number and device
+identifier of the file visited in the current buffer, or @code{nil} if no
file or a nonexistent file is visited. It is a permanent local,
unaffected by @code{kill-all-local-variables}.
-The value is normally a list of the form @code{(@var{filenum}
-@var{devnum})}. This pair of numbers uniquely identifies the file among
+The value is normally a list of the form @code{(@var{inodenum}
+@var{device})}. This tuple uniquely identifies the file among
all files accessible on the system. See the function
@code{file-attributes}, in @ref{File Attributes}, for more information
about them.
If @code{buffer-file-name} is the name of a symbolic link, then both
-numbers refer to the recursive target.
+@var{inodenum} and @var{device} refer to the recursive target of the link.
@end defvar
@defun get-file-buffer filename
diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi
index 60fc11a22ed..70e0f98f443 100644
--- a/doc/lispref/compile.texi
+++ b/doc/lispref/compile.texi
@@ -973,6 +973,24 @@ whether native-compilation is available should use this predicate.
This section documents the variables that control
native-compilation.
+@defvar inhibit-automatic-native-compilation
+If your Emacs has support for native compilation, Emacs will (by
+default) compile the Lisp files you're loading in the background, and
+then install the native-compiled versions of the functions. If you
+wish to disable this, you can set this variable to non-@code{nil}. If
+you want to set it permanently, this should probably be done from the
+early init file, since setting it in the normal init file is probably
+too late.
+
+While setting this variable disables automatic compilation of Lisp
+files, the compiler may still be invoked to install @dfn{trampolines}
+if any built-in functions are redefined. However, these trampolines
+will not get written to your cache directory.
+
+You can also use the @samp{EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION}
+environment variable to disable native compilation.
+@end defvar
+
@defopt native-comp-speed
This variable specifies the optimization level for native compilation.
Its value should be a number between @minus{}1 and 3. Values between
diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index d4520ebdee5..9035e7f6bbc 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -294,6 +294,48 @@ For example:
@end group
@end example
+It can be convenient to bind variables in conjunction with using a
+conditional. It's often the case that you compute a value, and then
+want to do something with that value if it's non-@code{nil}. The
+straightforward way to do that is to just write, for instance:
+
+@example
+(let ((result1 (do-computation)))
+ (when result1
+ (let ((result2 (do-more result1)))
+ (when result2
+ (do-something result2)))))
+@end example
+
+Since this is a very common pattern, Emacs provides a number of macros
+to make this easier and more readable. The above can be written the
+following way instead:
+
+@example
+(when-let ((result1 (do-computation))
+ (result2 (do-more result1)))
+ (do-something result2))
+@end example
+
+There's a number of variations on this theme, and they're briefly
+described below.
+
+@defmac if-let spec then-form else-forms...
+Evaluate each binding in @var{spec} in turn, like in @code{let*}
+(@pxref{Local Variables}, stopping if a binding value is @code{nil}.
+If all are non-@code{nil}, return the value of @var{then-form},
+otherwise the last form in @var{else-forms}.
+@end defmac
+
+@defmac when-let spec then-forms...
+Like @code{if-let}, but without @var{else-forms}.
+@end defmac
+
+@defmac while-let spec then-forms...
+Like @code{when-let}, but repeat until a binding in @var{spec} is
+@code{nil}. The return value is always @code{nil}.
+@end defmac
+
@node Combining Conditions
@section Constructs for Combining Conditions
@cindex combining conditions
@@ -2366,11 +2408,6 @@ of the @var{cleanup-forms} themselves exits nonlocally (via a
guaranteed to evaluate the rest of them. If the failure of one of the
@var{cleanup-forms} has the potential to cause trouble, then protect
it with another @code{unwind-protect} around that form.
-
-The number of currently active @code{unwind-protect} forms counts,
-together with the number of local variable bindings, against the limit
-@code{max-specpdl-size} (@pxref{Definition of max-specpdl-size,, Local
-Variables}).
@end defspec
For example, here we make an invisible buffer for temporary use, and
diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi
index 6ba35cffffe..204719e942b 100644
--- a/doc/lispref/customize.texi
+++ b/doc/lispref/customize.texi
@@ -1428,12 +1428,32 @@ emacs, The GNU Emacs Manual}.)
be a call to @code{deftheme}, and the last form should be a call to
@code{provide-theme}.
-@defmac deftheme theme &optional doc
+@defmac deftheme theme &optional doc &rest properties
This macro declares @var{theme} (a symbol) as the name of a Custom
theme. The optional argument @var{doc} should be a string describing
the theme; this is the description shown when the user invokes the
@code{describe-theme} command or types @kbd{?} in the @samp{*Custom
-Themes*} buffer.
+Themes*} buffer. The remaining arguments @var{properties} are used
+pass a property list with theme attributes.
+
+The following attributes are supported:
+
+@table @code
+@item :family
+A symbol designating what ``family'' a theme belongs to. A
+@dfn{family} of themes is a set of similar themes that differ by minor
+aspects, such as face colors that are meant for the light vs dark
+background of the frame.
+@item :kind
+A symbol. If a theme is enabled and this property has the value
+@code{color-scheme}, then the @code{theme-choose-variant} command will
+look for other available themes that belong to the same family in
+order to switch the themes. Other values are currently unspecified
+and should not be used.
+@item :background-mode
+A symbol, either @code{light} or @code{dark}. This attribute is
+currently unused, but should still be specified.
+@end table
Two special theme names are disallowed (using them causes an error):
@code{user} is a dummy theme that stores the user's direct
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 69b752688ea..64400ef9314 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5646,10 +5646,9 @@ Every image descriptor must include this property.
@item :file @var{file}
This says to load the image from file @var{file}. If @var{file} is
-not an absolute file name, it is expanded relative to the
-@file{images} subdirectory of @code{data-directory}, and failing that,
-relative to the directories listed by @code{x-bitmap-file-path}
-(@pxref{Face Attributes}).
+not an absolute file name, it is expanded relative to each of the
+directories mentioned by @code{image-load-path} (@pxref{Defining
+Images}).
@item :data @var{data}
This specifies the raw image data. Each image descriptor must have
@@ -6596,7 +6595,9 @@ Image type @code{webp}.
This function creates and returns an image descriptor which uses the
data in @var{file-or-data}. @var{file-or-data} can be a file name or
a string containing the image data; @var{data-p} should be @code{nil}
-for the former case, non-@code{nil} for the latter case.
+for the former case, non-@code{nil} for the latter case. If
+@var{file-or-data} is a relative file name, the function will search
+for it in directories mentioned in @code{image-load-path}.
The optional argument @var{type} is a symbol specifying the image type.
If @var{type} is omitted or @code{nil}, @code{create-image} tries to
@@ -6849,22 +6850,37 @@ keymap installed in the text properties (or overlays) that span the
displayed image. This keymap defines the following commands:
@table @kbd
-@item +
+@item i +
Increase the image size (@code{image-increase-size}). A prefix value
of @samp{4} means to increase the size by 40%. The default is 20%.
-@item -
+@item i -
Decrease the image size (@code{image-increase-size}). A prefix value
of @samp{4} means to decrease the size by 40%. The default is 20%.
-@item r
+@item i r
Rotate the image by 90 degrees clockwise (@code{image-rotate}).
A prefix means to rotate by 90 degrees counter-clockwise instead.
-@item o
+@item i h
+Flip the image horizontally (@code{image-flip-horizontally}).
+
+@item i v
+Flip the image vertically (@code{image-flip-vertically}).
+
+@item i o
Save the image to a file (@code{image-save}).
+
+@item i c
+Crop the image interactively (@code{image-crop}).
+
+@item i x
+Cut a rectangle from the image interactively (@code{image-cut}).
@end table
+The size and rotation commands are ``repeating'', which means that you
+can continue adjusting the image without using the @kbd{i} prefix.
+
@node Multi-Frame Images
@subsection Multi-Frame Images
@cindex multi-frame images
diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi
index 56f7b7bdfad..6a51489d8a4 100644
--- a/doc/lispref/edebug.texi
+++ b/doc/lispref/edebug.texi
@@ -1032,9 +1032,8 @@ program.
@itemize @bullet
@item
@vindex edebug-max-depth
-@code{max-lisp-eval-depth} (@pxref{Eval}) and @code{max-specpdl-size}
-(@pxref{Local Variables}) are both increased to reduce Edebug's impact
-on the stack. You could, however, still run out of stack space when
+@code{max-lisp-eval-depth} (@pxref{Eval}) is increased to reduce Edebug's
+impact on the stack. You could, however, still run out of stack space when
using Edebug. You can also enlarge the value of
@code{edebug-max-depth} if Edebug reaches the limit of recursion depth
instrumenting code that contains very large quoted lists.
diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi
index ed3cf56e098..11c321b32ed 100644
--- a/doc/lispref/eval.texi
+++ b/doc/lispref/eval.texi
@@ -830,7 +830,7 @@ This variable defines the maximum depth allowed in calls to @code{eval},
@code{apply}, and @code{funcall} before an error is signaled (with error
message @code{"Lisp nesting exceeds max-lisp-eval-depth"}).
-This limit, with the associated error when it is exceeded, is one way
+This limit, with the associated error when it is exceeded, is how
Emacs Lisp avoids infinite recursion on an ill-defined function. If
you increase the value of @code{max-lisp-eval-depth} too much, such
code can cause stack overflow instead. On some systems, this overflow
@@ -846,14 +846,11 @@ The depth limit counts internal uses of @code{eval}, @code{apply}, and
expressions, and recursive evaluation of function call arguments and
function body forms, as well as explicit calls in Lisp code.
-The default value of this variable is 800. If you set it to a value
+The default value of this variable is 1600. If you set it to a value
less than 100, Lisp will reset it to 100 if the given value is
reached. Entry to the Lisp debugger increases the value, if there is
little room left, to make sure the debugger itself has room to
execute.
-
-@code{max-specpdl-size} provides another limit on nesting.
-@xref{Definition of max-specpdl-size,, Local Variables}.
@end defopt
@defvar values
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 986fb22c75b..b26d4f10585 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -1253,14 +1253,6 @@ the @samp{smb} method. For all other connection methods, runtime
tests are performed.
@end defun
-@defun file-in-directory-p file dir
-This function returns @code{t} if @var{file} is a file in directory
-@var{dir}, or in a subdirectory of @var{dir}. It also returns
-@code{t} if @var{file} and @var{dir} are the same directory. It
-compares the truenames of the two directories. If @var{dir} does not
-name an existing directory, the return value is @code{nil}.
-@end defun
-
@defun vc-responsible-backend file
This function determines the responsible VC backend of the given
@var{file}. For example, if @file{emacs.c} is a file tracked by Git,
@@ -1412,14 +1404,17 @@ The file's inode number (@code{file-attribute-inode-number}),
a nonnegative integer.
@item
-The filesystem number of the device that the file is on
-@code{file-attribute-device-number}), an integer.
-This element and the file's inode number
-together give enough information to distinguish any two files on the
-system---no two files can have the same values for both of these
-numbers.
+The filesystem's identifier of the device that the file is on
+(@code{file-attribute-device-number}), an integer or a cons cell of
+two integers. The latter is sometimes used by remote files, in order
+to distinguish remote filesystems from local ones.
@end enumerate
+The file's inode and device together give enough information
+to distinguish any two files on the system---no two files can have the
+same values for both of these attributes. This tuple that uniquely
+identifies the file is returned by @code{file-attribute-file-identifier}.
+
For example, here are the file attributes for @file{files.texi}:
@example
@@ -2445,7 +2440,7 @@ You can use this function for directory names and for file names,
because it recognizes abbreviations even as part of the name.
@end defun
-@defun file-parent-directory filename
+@defun file-name-parent-directory filename
This function returns the directory name of the parent directory of
@var{filename}. If @var{filename} is at the root directory of the
filesystem, it returns @code{nil}. A relative @var{filename} is
@@ -3100,6 +3095,17 @@ is called with one argument (the file or directory) and should return
non-@code{nil} if that directory is the one it is looking for.
@end defun
+@cindex parent directory of file
+@cindex ancestor directory of file
+@cindex file, ancestor directory of
+@defun file-in-directory-p file dir
+This function returns @code{t} if @var{file} is a file in directory
+@var{dir}, or in a subdirectory of @var{dir}. It also returns
+@code{t} if @var{file} and @var{dir} are the same directory. It
+compares the truenames of the two directories. If @var{dir} does not
+name an existing directory, the return value is @code{nil}.
+@end defun
+
@defun directory-files-and-attributes directory &optional full-name match-regexp nosort id-format count
This is similar to @code{directory-files} in deciding which files
to report on and how to report their names. However, instead
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 262b86672da..8db6ad0fd32 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -407,7 +407,7 @@ Name of the physical monitor as @var{string}.
@item source
Source of the multi-monitor information as @var{string};
-e.g., @samp{XRandr} or @samp{Xinerama}.
+e.g., @samp{XRandR 1.5}, @samp{XRandr} or @samp{Xinerama}.
@end table
@var{x}, @var{y}, @var{width}, and @var{height} are integers.
@@ -2997,17 +2997,25 @@ explicit focus notifications.)
@end defun
@defvar after-focus-change-function
-This function is an extension point that code can use to receive a
-notification that focus has changed.
-
-This function is called with no arguments when Emacs notices that the
-set of focused frames may have changed. Code wanting to do something
-when frame focus changes should use @code{add-function} to add a
-function to this one, and in this added function, re-scan the set of
-focused frames, calling @code{frame-focus-state} to retrieve the last
-known focus state of each frame. Focus events are delivered
-asynchronously, and frame input focus according to an external system
-may not correspond to the notion of the Emacs selected frame.
+This function is called with no arguments when Emacs notices that a
+frame may have gotten or lost focus. Focus events are delivered
+asynchronously, and may not be delivered in the expected order, so
+code that wants to do something depending on the state of focused
+frames have go through all the frames and check.
+
+For instance, here's a simple example function that sets the
+background color based on whether the frame has focus or not:
+
+@lisp
+(add-function :after after-focus-change-function
+ #'my-change-background)
+(defun my-change-background ()
+ (dolist (frame (frame-list))
+ (pcase (frame-focus-state frame)
+ (`t (set-face-background 'default "black" frame))
+ (`nil (set-face-background 'default "#404040" frame)))))
+@end lisp
+
Multiple frames may appear to have input focus simultaneously due to
focus event delivery differences, the presence of multiple Emacs
terminals, and other factors, and code should be robust in the face of
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index 983dfe2ec59..8b858e0aa01 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -2476,11 +2476,12 @@ function, of the form @code{(@var{function} @var{args}@dots{})}, the macro
expander will call @var{expander} with that form as well as with
@var{args}@dots{}, and @var{expander} can either return a new expression to use
instead of the function call, or it can return just the form unchanged,
-to indicate that the function call should be left alone. @var{expander} can
-be a symbol, or it can be a form @code{(lambda (@var{arg}) @var{body})} in
-which case @var{arg} will hold the original function call expression, and the
-(unevaluated) arguments to the function can be accessed using the function's
-formal arguments.
+to indicate that the function call should be left alone.
+
+When @var{expander} is a lambda form it should be written with
+a single argument (i.e., be of the form @code{(lambda (@var{arg})
+@var{body})}) because the function's formal arguments are
+automatically added to the lambda's list of arguments for you.
@item (gv-expander @var{expander})
Declare @var{expander} to be the function to handle calls to the macro (or
diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi
index 154a7abeb63..65ad5f05542 100644
--- a/doc/lispref/help.texi
+++ b/doc/lispref/help.texi
@@ -827,7 +827,7 @@ if the user types the help character again.
Emacs can list functions based on various groupings. For instance,
@code{string-trim} and @code{mapconcat} are ``string'' functions, so
-@kbd{M-x shortdoc-display-group RET string RET} will give an overview
+@kbd{M-x shortdoc RET string RET} will give an overview
of functions that operate on strings.
The documentation groups are created with the
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 8d2089bad8b..ea1679f6934 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -3004,8 +3004,8 @@ Using @code{bool} can make programs easier to read and a bit faster than
using @code{int}. Although it is also OK to use @code{int}, @code{0}
and @code{1}, this older style is gradually being phased out. When
using @code{bool}, respect the limitations of the replacement
-implementation of @code{bool}, as documented in the source file
-@file{lib/stdbool.in.h}. In particular, boolean bitfields should be of type
+implementation of @code{bool}. In particular,
+boolean bitfields should be of type
@code{bool_bf}, not @code{bool}, so that they work correctly even when
compiling Objective C with standard GCC.
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 4e4f12dc324..c7fbdac1d76 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -662,7 +662,7 @@ and @code{define-overloadable-function} (see the commentary in
and @code{define-global-minor-mode}.
@item Other definition types:
-@code{defcustom}, @code{defgroup}, @code{defclass}
+@code{defcustom}, @code{defgroup}, @code{deftheme}, @code{defclass}
(@pxref{Top,EIEIO,,eieio,EIEIO}), and @code{define-skeleton}
(@pxref{Top,Autotyping,,autotype,Autotyping}).
@end table
diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi
index 71fee45c4a5..006966daedb 100644
--- a/doc/lispref/nonascii.texi
+++ b/doc/lispref/nonascii.texi
@@ -463,7 +463,7 @@ of character properties. In particular, Emacs supports the
@uref{https://www.unicode.org/reports/tr23/, Unicode Character Property
Model}, and the Emacs character property database is derived from the
Unicode Character Database (@acronym{UCD}). See the
-@uref{https://www.unicode.org/versions/Unicode14.0.0/ch04.pdf, Character
+@uref{https://www.unicode.org/versions/Unicode15.0.0/ch04.pdf, Character
Properties chapter of the Unicode Standard}, for a detailed
description of Unicode character properties and their meaning. This
section assumes you are already familiar with that chapter of the
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 35828018417..3e16ac0eb49 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -3175,6 +3175,9 @@ This is not detected by this function, and so a non-@code{nil} return
value does not guarantee that changes on @var{file} will be actually
notified.
+If @var{file} is a symlink, it doesn't follow that link. Just
+@var{file} itself will be watched.
+
@var{flags} is a list of conditions to set what will be watched for.
It can include the following symbols:
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 12c15e6f9a2..bc5a4cf24a6 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -698,6 +698,19 @@ the same type as @var{sequence}.
@end example
@end defun
+@defun seq-keep function sequence
+ This function returns a list of all non-@code{nil} results from
+calling @var{function} on the elements in @var{sequence}.
+
+@example
+@group
+(seq-keep #'cl-digit-char-p '(?6 ?a ?7))
+@result{} (6 7)
+@end group
+@end example
+
+@end defun
+
@defun seq-reduce function sequence initial-value
@cindex reducing sequences
This function returns the result of calling @var{function} with
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index 374381e5955..cf961e9e7c8 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -539,21 +539,10 @@ string or symbol, @code{string=} signals an error.
@result{} nil
@end example
-For technical reasons, a unibyte and a multibyte string are
-@code{equal} if and only if they contain the same sequence of
-character codes and all these codes are either in the range 0 through
-127 (@acronym{ASCII}) or 160 through 255 (@code{eight-bit-graphic}).
-However, when a unibyte string is converted to a multibyte string, all
-characters with codes in the range 160 through 255 are converted to
-characters with higher codes, whereas @acronym{ASCII} characters
-remain unchanged. Thus, a unibyte string and its conversion to
-multibyte are only @code{equal} if the string is all @acronym{ASCII}.
-Character codes 160 through 255 are not entirely proper in multibyte
-text, even though they can occur. As a consequence, the situation
-where a unibyte and a multibyte string are @code{equal} without both
-being all @acronym{ASCII} is a technical oddity that very few Emacs
-Lisp programmers ever get confronted with. @xref{Text
-Representations}.
+A unibyte and a multibyte string are equal in the sense of
+@code{string=} if and only if they contain the same sequence of
+character codes all being in the range 0--127 (@acronym{ASCII}).
+@xref{Text Representations}.
@end defun
@defun string-equal string1 string2
@@ -1293,6 +1282,11 @@ The order of specifications in @var{template} need not correspond to
the order of associations in @var{spec-alist}.
@end itemize
+REPLACEMENT can also be a function taking no arguments, and returning
+a string to be used for the replacement. It will only be called when
+the corresponding LETTER is used in the TEMPLATE. This is useful, for
+example, to avoid prompting for input unless it is needed.
+
The optional argument @var{ignore-missing} indicates how to handle
specification characters in @var{template} that are not found in
@var{spec-alist}. If it is @code{nil} or omitted, the function
diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi
index 336fa9c9182..ea1e086ebf1 100644
--- a/doc/lispref/symbols.texi
+++ b/doc/lispref/symbols.texi
@@ -613,7 +613,10 @@ file-local evaluation forms. @xref{File Local Variables}.
@item safe-local-variable
The value specifies a function for determining safe file-local values
-for the named variable. @xref{File Local Variables}.
+for the named variable. @xref{File Local Variables}. Since this
+value is consulted when loading files, the function should be
+efficient and should ideally not lead to loading any libraries to
+determine the safeness (e.g., it should not be an autoloaded function).
@item side-effect-free
@cindex @code{side-effect-free} property
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 8b859042ad0..509ce56725d 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -5321,9 +5321,12 @@ This has exactly the same effect as the previous example, but is more
efficient and safer (because it doesn't involve any string parsing or
interpolation).
-@code{sqlite-execute} returns the number of affected rows. For
-instance, an @samp{insert} statement will return @samp{1}, whereas an
-@samp{update} statement may return zero or a higher number.
+@code{sqlite-execute} usually returns the number of affected rows.
+For instance, an @samp{insert} statement will typically return
+@samp{1}, whereas an @samp{update} statement may return zero or a
+higher number. However, when using @acronym{SQL} statements like
+@w{@samp{insert into @dots{} returning @dots{}}} and the like, the values
+specified by @w{@samp{returning @dots{}}} will be returned instead.
Strings in SQLite are, by default, stored as @code{utf-8}, and
selecting a text column will decode the string using that charset.
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 80d6a01412b..1d891618dad 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -358,27 +358,6 @@ Variables}); a few variables have terminal-local bindings
like ordinary local bindings, but they are localized depending on
where you are in Emacs.
-@defopt max-specpdl-size
-@anchor{Definition of max-specpdl-size}
-@cindex variable limit error
-@cindex evaluation error
-@cindex infinite recursion
-This variable defines the limit on the total number of local variable
-bindings and @code{unwind-protect} cleanups (@pxref{Cleanups,,
-Cleaning Up from Nonlocal Exits}) that are allowed before Emacs
-signals an error (with data @code{"Variable binding depth exceeds
-max-specpdl-size"}).
-
-This limit, with the associated error when it is exceeded, is one way
-that Lisp avoids infinite recursion on an ill-defined function.
-@code{max-lisp-eval-depth} provides another limit on depth of nesting.
-@xref{Definition of max-lisp-eval-depth,, Eval}.
-
-The default value is 1600. Entry to the Lisp debugger increases the
-value, if there is little room left, to make sure the debugger itself
-has room to execute.
-@end defopt
-
@node Void Variables
@section When a Variable is Void
@cindex @code{void-variable} error
@@ -2635,15 +2614,15 @@ is a set of forms that can be generalized variables in Lisp.
The @code{setf} macro is the most basic way to operate on generalized
variables. The @code{setf} form is like @code{setq}, except that it
-accepts arbitrary place forms on the left side rather than just
-symbols. For example, @code{(setf (car a) b)} sets the car of
-@code{a} to @code{b}, doing the same operation as @code{(setcar a b)},
-but without you having to use two separate functions for setting and
-accessing this type of place.
+accepts arbitrary place forms in the first (left) argument of each
+pair rather than just symbols. For example, @code{(setf (car a) b)}
+sets the car of @code{a} to @code{b}, doing the same operation as
+@code{(setcar a b)}, but without you having to use two separate
+functions for setting and accessing this type of place.
@defmac setf [place form]@dots{}
-This macro evaluates @var{form} and stores it in @var{place}, which
-must be a valid generalized variable form. If there are several
+This macro evaluates @var{form} and stores its value in @var{place},
+which must be a valid generalized variable form. If there are several
@var{place} and @var{form} pairs, the assignments are done sequentially
just as with @code{setq}. @code{setf} returns the value of the last
@var{form}.
@@ -2718,7 +2697,17 @@ a
@result{} ("hello" "wood")
@end example
-@c FIXME? Also 'eq'? (see gv.el)
+@item
+The @code{if} and @code{cond} conditionals will work as generalized
+variables. For instance, this will set either the @code{foo} or the
+@code{bar} variable to @code{zot}:
+
+@example
+(setf (if (zerop (random 2))
+ foo
+ bar)
+ 'zot)
+@end example
@end itemize
@noindent
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 33d0150a939..e946a408fd6 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -6492,7 +6492,7 @@ during redisplay provided a significant, non-scrolling change of a
window has been detected. For simplicity, these hooks and the
functions they call will be collectively referred to as @dfn{window
change functions}. As any hook, these hooks can be set either
-globally of buffer-locally via the @var{local} argument of
+globally or buffer-locally via the @var{local} argument of
@code{add-hook} (@pxref{Setting Hooks}) when the hook is installed.
@cindex window buffer change
@@ -6684,32 +6684,32 @@ time window change functions were run for @var{window}'s frame. If it
returns @code{nil}, @var{window} has been created after that. If it
returns @code{t}, @var{window} was not shown at that time but has been
restored from a previously saved window configuration afterwards.
-Otherwise, the return value is the buffer shown by @code{window} at
+Otherwise, the return value is the buffer shown by @var{window} at
that time.
@end defun
@defun window-old-pixel-width &optional window
This function returns the total pixel width of @var{window} the
-last time window change functions found @code{window} live on its
-frame. It is zero if @code{window} was created after that.
+last time window change functions found @var{window} live on its
+frame. It is zero if @var{window} was created after that.
@end defun
@defun window-old-pixel-height &optional window
This function returns the total pixel height of @var{window} the last
-time window change functions found @code{window} live on its frame.
-It is zero if @code{window} was created after that.
+time window change functions found @var{window} live on its frame.
+It is zero if @var{window} was created after that.
@end defun
@defun window-old-body-pixel-width &optional window
This function returns the pixel width of @var{window}'s text area the
-last time window change functions found @code{window} live on its
-frame. It is zero if @code{window} was created after that.
+last time window change functions found @var{window} live on its
+frame. It is zero if @var{window} was created after that.
@end defun
@defun window-old-body-pixel-height &optional window
This function returns the pixel height of @var{window}'s text area the
-last time window change functions found @code{window} live on its
-frame. It is zero if @code{window} was created after that.
+last time window change functions found @var{window} live on its
+frame. It is zero if @var{window} was created after that.
@end defun
In order to find out which window or frame was selected the last time
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 98f59b89c01..89a340e7343 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -10392,7 +10392,6 @@ memory than it would otherwise, but it's guaranteed to fix the problem.
@cindex Recursion depth
@cindex ``Computation got stuck'' message
@cindex @code{max-lisp-eval-depth}
-@cindex @code{max-specpdl-size}
Calc uses recursion in many of its calculations. Emacs Lisp keeps a
variable @code{max-lisp-eval-depth} which limits the amount of recursion
possible in an attempt to recover from program bugs. If a calculation
@@ -10406,9 +10405,6 @@ is also an @kbd{I M} (@code{calc-less-recursion-depth}) command which
decreases this limit by a factor of two, down to a minimum value of 200.
The default value is 1000.
-These commands also double or halve @code{max-specpdl-size}, another
-internal Lisp recursion limit. The minimum value for this limit is 600.
-
@node Caches
@subsection Caches
diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index 1f12c30b1f8..ab41737794c 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -580,7 +580,7 @@ you are going to be editing AWK files, @file{README} describes how to
configure your (X)Emacs so that @ccmode{} will supersede the obsolete
@code{awk-mode.el} which might have been supplied with your (X)Emacs.
@ccmode{} might not work with older versions of Emacs or XEmacs. See
-the @ccmode{} release notes at @uref{http://cc-mode.sourceforge.net}
+the @ccmode{} release notes at @uref{https://cc-mode.sourceforge.net}
for the latest information on Emacs version and package compatibility
(@pxref{Updating CC Mode}).
@@ -3170,7 +3170,7 @@ E. Jones' Filladapt package@footnote{It's available from
lack a feature that makes it work suboptimally when
@code{c-comment-prefix-regexp} matches the empty string (which it does
by default). A patch for that is available from
-@uref{http://cc-mode.sourceforge.net/,, the CC Mode web site}.},
+@uref{https://cc-mode.sourceforge.net/,, the CC Mode web site}.},
@c 2005/11/22: The above is still believed to be the case.
which handles things like bulleted lists nicely. There's a convenience
function @code{c-setup-filladapt} that tunes the relevant variables in
@@ -7583,7 +7583,7 @@ have old versions of @ccmode{} and so should be upgraded. Access to the
compatibility, etc.@: are all available on the web site:
@quotation
-@uref{http://cc-mode.sourceforge.net/}
+@uref{https://cc-mode.sourceforge.net/}
@end quotation
@@ -7617,7 +7617,7 @@ the GNU Bug Tracker at @url{https://debbugs.gnu.org}, then sends it on
to @email{bug-cc-mode@@gnu.org}. You can also send reports, other
questions, and suggestions (kudos?@: @t{;-)} to that address. It's a
mailing list which you can join or browse an archive of; see the web site at
-@uref{http://cc-mode.sourceforge.net/} for further details.
+@uref{https://cc-mode.sourceforge.net/} for further details.
@cindex announcement mailing list
If you want to get announcements of new @ccmode{} releases, send the
diff --git a/doc/misc/ede.texi b/doc/misc/ede.texi
index 9867883b24a..c0c2ef93d94 100644
--- a/doc/misc/ede.texi
+++ b/doc/misc/ede.texi
@@ -1031,8 +1031,9 @@ superclasses. In this way, specific behaviors such as how a project
is saved, or how a target is compiled can be customized by a project
author in detail. @ede{} communicates to these project objects via an
API using methods. The commands you use in @ede{} mode are high-level
-functional wrappers over these methods. @xref{Top,,, eieio, EIEIO manual}. For
-details on using @eieio{} to extending classes, and writing methods.
+functional wrappers over these methods. @xref{Top,,, eieio, EIEIO
+manual} for details on using @eieio{} to extending classes, and
+writing methods.
If you intend to extend @ede{}, it is most likely that a new target type is
needed in one of the existing project types. The rest of this chapter
diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi
index 46c257e42e5..b58f6be7581 100644
--- a/doc/misc/efaq-w32.texi
+++ b/doc/misc/efaq-w32.texi
@@ -1744,7 +1744,7 @@ date now, so no concrete pointers are available.
You will need an implementation of TeX for Windows.
A number of implementations are listed on the
-@uref{http://www.tug.org/interest.html#free, TeX Users Group} website.
+@uref{https://www.tug.org/interest.html#free, TeX Users Group} website.
@node Spell check
@section How do I perform spell checks?
@@ -1899,7 +1899,7 @@ Christopher Payne wrote a Visual Studio add-in that makes Emacs the
default text editor, this has now been taken over by Jeff Paquette.
See the following two URLs for details:
@itemize
-@item @uref{http://sourceforge.net/projects/visemacs/} for the latest version.
+@item @uref{https://sourceforge.net/projects/visemacs/} for the latest version.
@item @uref{http://www.smathers.net/VisEmacs.htm} for notes on usage.
@end itemize
@@ -2039,7 +2039,7 @@ this option is set. (I don't see it on VC++ 4.0.)
@cindex Borland C++, integration with Emacs
Jonathan Arnold has written an
-@uref{http://www.buddydog.org/C++Builder/c++builder.html, EmacsEdit
+@uref{https://www.buddydog.org/C++Builder/c++builder.html, EmacsEdit
``expert''} for interfacing C++ Builder and Emacs.
@node Version control
@@ -2194,7 +2194,7 @@ to port software to Windows.
@cindex image libraries, gnuwin32
@cindex image libraries, development
-@uref{http://gnuwin32.sourceforge.net/}
+@uref{https://gnuwin32.sourceforge.net/}
GnuWin32 provides precompiled native Windows ports of a wide selection
of Free software and libraries. Unfortunately, the ports are
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index ccaca1d017c..23e3b086a3a 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -1810,9 +1810,6 @@ optional display. Alternatively, you can use the
customize @code{display-line-numbers-type} with the same value as you
would use with @code{display-line-numbers}.
-There is also the @samp{linum} package which will henceforth become
-obsolete. We recommend using @samp{display-line-numbers} instead.
-
@node Displaying the current file name in the titlebar
@section How can I modify the titlebar to contain the current file name?
@cindex Titlebar, displaying the current file name in
@@ -3625,13 +3622,13 @@ To build Emacs from source for MS-DOS, see the instructions in the file
on plain DOS, and also on all versions of MS-Windows from version 3.X
onwards, including Windows XP and Vista. Pre-built binaries may be
available at
-@uref{http://www.delorie.com/pub/djgpp/current/v2gnu/emacs.README}
+@uref{https://www.delorie.com/pub/djgpp/current/v2gnu/emacs.README}
For a list of other implementations of Emacs (and Emacs
look-alikes), consult the list of ``Emacs implementations and literature,''
available at
-@uref{http://www.finseth.com/emacs.html}
+@uref{https://www.finseth.com/emacs.html}
Note that while many of these programs look similar to Emacs, they often
lack certain features, such as the Emacs Lisp extension language.
@@ -3760,7 +3757,7 @@ Various spell-checkers are compatible with Emacs, including:
@table @b
@item Hunspell
-@uref{http://hunspell.sourceforge.net/}
+@uref{https://hunspell.github.io/}
@item GNU Aspell
@uref{http://aspell.net/}
diff --git a/doc/misc/eieio.texi b/doc/misc/eieio.texi
index 18a2b74033e..b1ec5c0dce7 100644
--- a/doc/misc/eieio.texi
+++ b/doc/misc/eieio.texi
@@ -193,7 +193,7 @@ also differs in some other aspects which are mentioned below (also
@enumerate
@item
A structured framework for the creation of basic classes with attributes
-and methods using singular inheritance similar to CLOS.
+and methods using inheritance similar to CLOS.
@item
Type checking, and slot unbinding.
@item
@@ -225,11 +225,6 @@ lacks:
@table @asis
-@item Method dispatch
-EIEO does not support method dispatch for built-in types and multiple
-arguments types. In other words, method dispatch only looks at the
-first argument, and this one must be an @eieio{} type.
-
@item Support for metaclasses
There is just one default metaclass, @code{eieio-default-superclass},
and you cannot define your own. The @code{:metaclass} tag in
@@ -856,11 +851,6 @@ You can also create a generic method with @code{cl-defmethod}
(@pxref{Methods}). When a method is created and there is no generic
method in place with that name, then a new generic will be created,
and the new method will use it.
-
-In CLOS, a generic method can also be used to provide an argument list
-and dispatch precedence for all the arguments. In @eieio{},
-dispatching only occurs for the first argument, so the @var{arglist}
-is not used.
@end defmac
@node Methods
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index bc3b21d019e..0ee33f2c2a9 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -1677,7 +1677,7 @@ inserting it like with @code{>>> @var{file}}.
@item >&@var{other-fd}
@itemx @var{fd}>&@var{other-fd}
Duplicate the file descriptor @var{other-fd} to @var{fd} (or 1 if
-unspecified). The order in which this is used is signficant, so
+unspecified). The order in which this is used is significant, so
@example
@var{command} > @var{file} 2>&1
diff --git a/doc/misc/gnus-coding.texi b/doc/misc/gnus-coding.texi
deleted file mode 100644
index 0858432acf2..00000000000
--- a/doc/misc/gnus-coding.texi
+++ /dev/null
@@ -1,227 +0,0 @@
-\input texinfo
-
-@setfilename gnus-coding.info
-@settitle Gnus Coding Style and Maintenance Guide
-@include docstyle.texi
-@syncodeindex fn cp
-@syncodeindex vr cp
-@syncodeindex pg cp
-
-@copying
-Copyright @copyright{} 2004--2005, 2007--2022 Free Software Foundation,
-Inc.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover Texts being ``A GNU Manual'',
-and with the Back-Cover Texts as in (a) below. A copy of the license
-is included in the section entitled ``GNU Free Documentation License''.
-
-(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
-modify this GNU manual.''
-@end quotation
-@end copying
-
-
-@titlepage
-@title Gnus Coding Style and Maintenance Guide
-
-@author by Reiner Steib <Reiner.Steib@@gmx.de>
-
-@insertcopying
-@end titlepage
-
-@c Obviously this is only a very rudimentary draft. We put it in the
-@c repository anyway hoping that it might annoy someone enough to fix
-@c it. ;-) Fixing only a paragraph also is appreciated.
-
-@ifnottex
-@node Top
-@top Gnus Coding Style and Maintenance Guide
-This manual describes @dots{}
-
-@insertcopying
-@end ifnottex
-
-@menu
-* Gnus Coding Style:: Gnus Coding Style
-* Gnus Maintenance Guide:: Gnus Maintenance Guide
-* GNU Free Documentation License:: The license for this documentation.
-@end menu
-
-@c @ref{Gnus Reference Guide, ,Gnus Reference Guide, gnus, The Gnus Newsreader}
-
-@node Gnus Coding Style
-@chapter Gnus Coding Style
-@section Dependencies
-
-The Gnus distribution contains a lot of libraries that have been written
-for Gnus and used intensively for Gnus. But many of those libraries are
-useful on their own. E.g., other Emacs Lisp packages might use the
-@acronym{MIME} library @xref{Top, ,Top, emacs-mime, The Emacs MIME
-Manual}.
-
-@subsection General purpose libraries
-
-@table @file
-
-@item netrc.el
-@file{.netrc} parsing functionality.
-@c As of 2005-10-21...
-There are no Gnus dependencies in this file.
-
-@item format-spec.el
-Functions for formatting arbitrary formatting strings.
-@c As of 2005-10-21...
-There are no Gnus dependencies in this file.
-
-@item hex-util.el
-Functions to encode/decode hexadecimal string.
-@c As of 2007-08-25...
-There are no Gnus dependencies in these files.
-@end table
-
-@subsection Encryption and security
-
-@table @file
-@item encrypt.el
-File encryption routines
-@c As of 2005-10-25...
-There are no Gnus dependencies in this file.
-
-@item password.el
-Read passwords from user, possibly using a password cache.
-@c As of 2005-10-21...
-There are no Gnus dependencies in this file.
-
-@item sha1.el
-SHA1 Secure Hash Algorithm.
-@c As of 2007-08-25...
-There are no Gnus dependencies in these files.
-@end table
-
-@subsection Networking
-
-@table @file
-@item dig.el
-Domain Name System dig interface.
-@c As of 2005-10-21...
-There are no serious Gnus dependencies in this file. Uses
-@code{gnus-run-mode-hooks} (a wrapper function).
-
-@item dns.el, dns-mode.el
-Domain Name Service lookups.
-@c As of 2005-10-21...
-There are no Gnus dependencies in these files.
-@end table
-
-@subsection Mail and News related RFCs
-
-@table @file
-@item pop3.el
-Post Office Protocol (RFC 1460) interface.
-@c As of 2005-10-21...
-There are no Gnus dependencies in this file.
-
-@item imap.el
-@acronym{IMAP} library.
-@c As of 2005-10-21...
-There are no Gnus dependencies in this file.
-
-@item ietf-drums.el
-Functions for parsing RFC 2822 headers.
-@c As of 2005-10-21...
-There are no Gnus dependencies in this file.
-
-@item rfc1843.el
-HZ (rfc1843) decoding. HZ is a data format for exchanging files of
-arbitrarily mixed Chinese and @acronym{ASCII} characters.
-@c As of 2005-10-21...
-@code{rfc1843-gnus-setup} seem to be useful only for Gnus. Maybe this
-function should be relocated to remove dependencies on Gnus. Other
-minor dependencies: @code{gnus-newsgroup-name} could be eliminated by
-using an optional argument to @code{rfc1843-decode-article-body}.
-
-@item rfc2045.el
-Functions for decoding rfc2045 headers
-@c As of 2007-08-25...
-There are no Gnus dependencies in these files.
-
-@item rfc2047.el
-Functions for encoding and decoding rfc2047 messages
-@c As of 2007-08-25...
-There are no Gnus dependencies in these files.
-@c
-Only a couple of tests for gnusy symbols.
-
-@item rfc2104.el
-RFC2104 Hashed Message Authentication Codes
-@c As of 2007-08-25...
-There are no Gnus dependencies in these files.
-
-@item rfc2231.el
-Functions for decoding rfc2231 headers
-@c As of 2007-08-25...
-There are no Gnus dependencies in these files.
-
-@item flow-fill.el
-Interpret RFC2646 "flowed" text.
-@c As of 2005-10-27...
-There are no Gnus dependencies in this file.
-
-@item uudecode.el
-Elisp native uudecode.
-@c As of 2005-12-06...
-There are no Gnus dependencies in this file.
-@c ... but the custom group is gnus-extract.
-
-@item canlock.el
-Functions for Cancel-Lock feature
-@c Cf. draft-ietf-usefor-cancel-lock-01.txt
-@c Although this draft has expired, Canlock-Lock revived in 2007 when
-@c major news providers (e.g., news.individual.org) started to use it.
-@c As of 2007-08-25...
-There are no Gnus dependencies in these files.
-
-@end table
-
-@subsection message
-
-All message composition from Gnus (both mail and news) takes place in
-Message mode buffers. Message mode is intended to be a replacement for
-Emacs mail mode. There should be no Gnus dependencies in
-@file{message.el}. Alas it is not anymore. Patches and suggestions to
-remove the dependencies are welcome.
-
-@c message.el requires nnheader which requires gnus-util.
-
-@subsection Emacs @acronym{MIME}
-
-The files @file{mml*.el} and @file{mm-*.el} provide @acronym{MIME}
-functionality for Emacs.
-
-@acronym{MML} (@acronym{MIME} Meta Language) is supposed to be
-independent from Gnus. Alas it is not anymore. Patches and suggestions
-to remove the dependencies are welcome.
-
-@subsection Gnus backends
-
-The files @file{nn*.el} provide functionality for accessing NNTP
-(@file{nntp.el}), IMAP (@file{nnimap.el}) and several other Mail back
-ends (probably @file{nnml.el}, @file{nnfolder.el} and
-@file{nnmaildir.el} are the most widely used mail back ends).
-
-@c mm-uu requires nnheader which requires gnus-util. message.el also
-@c requires nnheader.
-
-
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-@include doclicense.texi
-
-@c Local Variables:
-@c mode: texinfo
-@c coding: utf-8
-@c End:
diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi
index 6d09fd4ec96..7cb5621b694 100644
--- a/doc/misc/gnus-faq.texi
+++ b/doc/misc/gnus-faq.texi
@@ -49,23 +49,23 @@ This is the Gnus Frequently Asked Questions list.
Gnus is a Usenet Newsreader and Electronic Mail User Agent implemented
as a part of Emacs. It's been around in some form since the early
1990s, and has been distributed as a standard part of Emacs for much
-of that time. Gnus 5 is the latest (and greatest) incarnation. The
+of that time. Gnus 5 is the latest (and greatest) incarnation. The
original version was called GNUS, and was written by Masanobu UMEDA@.
When autumn crept up in 1994, Lars Magne Ingebrigtsen grew bored and
decided to rewrite Gnus.
Its biggest strength is the fact that it is extremely
-customizable. It is somewhat intimidating at first glance, but
+customizable. It is somewhat intimidating at first glance, but
most of the complexity can be ignored until you're ready to take
-advantage of it. If you receive a reasonable volume of e-mail
+advantage of it. If you receive a reasonable volume of e-mail
(you're on various mailing lists), or you would like to read
high-volume mailing lists but cannot keep up with them, or read
high volume newsgroups or are just bored, then Gnus is what you
want.
-This FAQ was maintained by Justin Sheehy until March 2002. He
+This FAQ was maintained by Justin Sheehy until March 2002. He
would like to thank Steve Baur and Per Abrahamsen for doing a wonderful
-job with this FAQ before him. We would like to do the same: thanks,
+job with this FAQ before him. We would like to do the same: thanks,
Justin!
The information contained here was compiled with the assistance
@@ -117,7 +117,7 @@ development version that became Gnus 5.12.
@menu
* FAQ 2-1:: Every time I start Gnus I get a message "Gnus auto-save
- file exists. Do you want to read it?", what does this mean and
+ file exists. Do you want to read it?", what does this mean and
how to prevent it?
* FAQ 2-2:: Gnus doesn't remember which groups I'm subscribed to,
what's this?
@@ -133,7 +133,7 @@ development version that became Gnus 5.12.
@subsubheading Question 2.1
Every time I start Gnus I get a message "Gnus auto-save
-file exists. Do you want to read it?", what does this mean
+file exists. Do you want to read it?", what does this mean
and how to prevent it?
@subsubheading Answer
@@ -168,8 +168,8 @@ How to change the format of the lines in Group buffer?
@subsubheading Answer
You've got to tweak the value of the variable
-gnus-group-line-format. See the manual node "Group Line
-Specification" for information on how to do this. An
+gnus-group-line-format. See the manual node "Group Line
+Specification" for information on how to do this. An
example for this (guess from whose .gnus :-)):
@example
@@ -192,11 +192,11 @@ Linux under the topic linux, all dealing with music under
the topic music and all dealing with scottish music under
the topic scottish which is a subtopic of music.
-To enter topic mode, just hit t while in Group buffer. Now
+To enter topic mode, just hit t while in Group buffer. Now
you can use @samp{T n} to create a topic
at point and @samp{T m} to move a group to
-a specific topic. For more commands see the manual or the
-menu. You might want to include the %P specifier at the
+a specific topic. For more commands see the manual or the
+menu. You might want to include the %P specifier at the
beginning of your gnus-group-line-format variable to have
the groups nicely indented.
@@ -231,7 +231,7 @@ hit @samp{C-y}.
possible?
* FAQ 3-7:: And how about local spool files?
* FAQ 3-8:: OK, reading news works now, but I want to be able to
- read my mail with Gnus, too. How to do it?
+ read my mail with Gnus, too. How to do it?
* FAQ 3-9:: And what about IMAP?
* FAQ 3-10:: At the office we use one of those MS Exchange servers,
can I use Gnus to read my mail from it?
@@ -248,8 +248,8 @@ but it only says "nntp (news) open error", what to do?
@subsubheading Answer
-You've got to tell Gnus where to fetch the news from. Read
-the documentation for information on how to do this. As a
+You've got to tell Gnus where to fetch the news from. Read
+the documentation for information on how to do this. As a
first start, put those lines in @file{~/.gnus.el}:
@example
@@ -279,7 +279,7 @@ directory Emacs chooses will most certainly not be what
you want, so let's do it the correct way.
The first thing you've got to do is to
create a suitable directory (no blanks in names
-please), e.g., c:\myhome. Then you must set the environment
+please), e.g., c:\myhome. Then you must set the environment
variable HOME to this directory. To do this under Windows 9x
or Me include the line
@@ -290,7 +290,7 @@ SET HOME=C:\myhome
in your autoexec.bat and reboot. Under NT, 2000 and XP, hit
Winkey+Pause/Break to enter system options (if it doesn't work, go
-to Control Panel -> System -> Advanced). There you'll find the
+to Control Panel -> System -> Advanced). There you'll find the
possibility to set environment variables. Create a new one with
name HOME and value C:\myhome. Rebooting is not necessary.
@@ -333,8 +333,8 @@ subscribe to a group.
If you know the name of the group say @samp{U
name.of.group @key{RET}} in group buffer (use the
-tab-completion Luke). Otherwise hit ^ in group buffer,
-this brings you to the server buffer. Now place point (the
+tab-completion Luke). Otherwise hit ^ in group buffer,
+this brings you to the server buffer. Now place point (the
cursor) over the server which carries the group you want,
hit @samp{@key{RET}}, move point to the group
you want to subscribe to and say @samp{u}
@@ -349,7 +349,7 @@ post on this server as well as I am, what's that?
@subsubheading Answer
Some providers allow restricted anonymous access and full
-access only after authorization. To make Gnus send authinfo
+access only after authorization. To make Gnus send authinfo
to those servers append
@example
@@ -366,8 +366,8 @@ I want Gnus to fetch news from several servers, is this possible?
@subsubheading Answer
-Of course. You can specify more sources for articles in the
-variable gnus-secondary-select-methods. Add something like
+Of course. You can specify more sources for articles in the
+variable gnus-secondary-select-methods. Add something like
this in @file{~/.gnus.el}:
@example
@@ -418,25 +418,25 @@ to post articles, see the Gnus manual on how to do this.
@subsubheading Question 3.8
OK, reading news works now, but I want to be able to read my mail
-with Gnus, too. How to do it?
+with Gnus, too. How to do it?
@subsubheading Answer
That's a bit harder since there are many possible sources
for mail, many possible ways for storing mail and many
-different ways for sending mail. The most common cases are
+different ways for sending mail. The most common cases are
these: 1: You want to read your mail from a pop3 server and
send them directly to a SMTP Server 2: Some program like
fetchmail retrieves your mail and stores it on disk from
-where Gnus shall read it. Outgoing mail is sent by
-Sendmail, Postfix or some other MTA@. Sometimes, you even
+where Gnus shall read it. Outgoing mail is sent by
+Sendmail, Postfix or some other MTA@. Sometimes, you even
need a combination of the above cases.
However, the first thing to do is to tell Gnus in which way
it should store the mail, in Gnus terminology which back end
-to use. Gnus supports many different back ends, the most
-commonly used one is nnml. It stores every mail in one file
-and is therefore quite fast. However you might prefer a one
+to use. Gnus supports many different back ends, the most
+commonly used one is nnml. It stores every mail in one file
+and is therefore quite fast. However you might prefer a one
file per group approach if your file system has problems with
many small files, the nnfolder back end is then probably the
choice for you. To use nnml add the following to @file{~/.gnus.el}:
@@ -453,7 +453,7 @@ As you might have guessed, if you want nnfolder, it's
@end example
@noindent
-Now we need to tell Gnus, where to get its mail from. If
+Now we need to tell Gnus, where to get its mail from. If
it's a POP3 server, then you need something like this:
@example
@@ -465,7 +465,7 @@ it's a POP3 server, then you need something like this:
@noindent
Make sure @file{~/.gnus.el} isn't readable to others if you store
-your password there. If you want to read your mail from a
+your password there. If you want to read your mail from a
traditional spool file on your local machine, it's
@example
@@ -499,10 +499,10 @@ mail, it's
Where :suffix ".prcml" tells Gnus only to use files with the
suffix .prcml.
-OK, now you only need to tell Gnus how to send mail. If you
+OK, now you only need to tell Gnus how to send mail. If you
want to send mail via sendmail (or whichever MTA is playing
the role of sendmail on your system), you don't need to do
-anything. However, if you want to send your mail to an
+anything. However, if you want to send your mail to an
SMTP Server you need the following in your @file{~/.gnus.el}
@example
@@ -519,9 +519,9 @@ And what about IMAP?
@subsubheading Answer
-There are two ways of using IMAP with Gnus. The first one is
+There are two ways of using IMAP with Gnus. The first one is
to use IMAP like POP3, that means Gnus fetches the mail from
-the IMAP server and stores it on disk. If you want to do
+the IMAP server and stores it on disk. If you want to do
this (you don't really want to do this) add the following to
@file{~/.gnus.el}
@@ -586,7 +586,7 @@ each POP3 mail source. @xref{Mail Source Specifiers}, for details on
@subsection Reading messages
@menu
-* FAQ 4-1:: When I enter a group, all read messages are gone. How to
+* FAQ 4-1:: When I enter a group, all read messages are gone. How to
view them again?
* FAQ 4-2:: How to tell Gnus to show an important message every time
I enter a group, even when it's read?
@@ -595,7 +595,7 @@ each POP3 mail source. @xref{Mail Source Specifiers}, for details on
* FAQ 4-5:: How can I change the headers Gnus displays by default at
the top of the article buffer?
* FAQ 4-6:: I'd like Gnus NOT to render HTML-mails but show me the
- text part if it's available. How to do it?
+ text part if it's available. How to do it?
* FAQ 4-7:: Can I use some other browser than shr to render my
HTML-mails?
* FAQ 4-8:: Is there anything I can do to make poorly formatted
@@ -609,7 +609,7 @@ each POP3 mail source. @xref{Mail Source Specifiers}, for details on
those?
* FAQ 4-12:: The number of total messages in a group which Gnus
displays in group buffer is by far to high, especially in mail
- groups. Is this a bug?
+ groups. Is this a bug?
* FAQ 4-13:: I don't like the layout of summary and article buffer,
how to change it? Perhaps even a three pane display?
* FAQ 4-14:: I don't like the way the Summary buffer looks, how to
@@ -621,15 +621,15 @@ each POP3 mail source. @xref{Mail Source Specifiers}, for details on
@node FAQ 4-1
@subsubheading Question 4.1
-When I enter a group, all read messages are gone. How to view them again?
+When I enter a group, all read messages are gone. How to view them again?
@subsubheading Answer
If you enter the group by saying
@samp{@key{RET}}
-in group buffer with point over the group, only unread and ticked messages are loaded. Say
+in group buffer with point over the group, only unread and ticked messages are loaded. Say
@samp{C-u @key{RET}}
-instead to load all available messages. If you want only the 300 newest say
+instead to load all available messages. If you want only the 300 newest say
@samp{C-u 300 @key{RET}}
Loading only unread messages can be annoying if you have threaded view enabled, say
@@ -658,9 +658,9 @@ enter a group, even when it's read?
@subsubheading Answer
-You can tick important messages. To do this hit
+You can tick important messages. To do this hit
@samp{u} while point is in summary buffer
-over the message. When you want to remove the mark, hit
+over the message. When you want to remove the mark, hit
either @samp{d} (this deletes the tick
mark and set's unread mark) or @samp{M c}
(which deletes all marks for the message).
@@ -700,7 +700,7 @@ the top of the article buffer?
The variable gnus-visible-headers controls which headers
are shown, its value is a regular expression, header lines
-which match it are shown. So if you want author, subject,
+which match it are shown. So if you want author, subject,
date, and if the header exists, Followup-To and MUA / NUA
say this in @file{~/.gnus.el}:
@@ -715,7 +715,7 @@ say this in @file{~/.gnus.el}:
@subsubheading Question 4.6
I'd like Gnus NOT to render HTML-mails but show me the
-text part if it's available. How to do it?
+text part if it's available. How to do it?
@subsubheading Answer
@@ -728,7 +728,7 @@ Say
@end example
@noindent
-in @file{~/.gnus.el}. If you don't want HTML rendered, even if there's no text alternative add
+in @file{~/.gnus.el}. If you don't want HTML rendered, even if there's no text alternative add
@example
(setq mm-automatic-display (remove "text/html" mm-automatic-display))
@@ -764,7 +764,7 @@ more readable?
Gnus offers you several functions to ``wash'' incoming mail, you can
find them if you browse through the menu, item
-Article->Washing. The most interesting ones are probably ``Wrap
+Article->Washing. The most interesting ones are probably ``Wrap
long lines'' (@samp{W w}), ``Decode ROT13''
(@samp{W r}) and ``Outlook Deuglify'' which repairs
the dumb quoting used by many users of Microsoft products
@@ -781,40 +781,40 @@ highlight more interesting ones in some way?
@subsubheading Answer
-You want Scoring. Scoring means, that you define rules
-which assign each message an integer value. Depending on
+You want Scoring. Scoring means, that you define rules
+which assign each message an integer value. Depending on
the value the message is highlighted in summary buffer (if
it's high, say +2000) or automatically marked read (if the
value is low, say @minus{}800) or some other action happens.
There are basically three ways of setting up rules which assign
-the scoring-value to messages. The first and easiest way is to set
-up rules based on the article you are just reading. Say you're
+the scoring-value to messages. The first and easiest way is to set
+up rules based on the article you are just reading. Say you're
reading a message by a guy who always writes nonsense and you want
-to ignore his messages in the future. Hit
+to ignore his messages in the future. Hit
@samp{L}, to set up a rule which lowers the score.
Now Gnus asks you which the criteria for lowering the Score shall
-be. Hit @samp{?} twice to see all possibilities,
+be. Hit @samp{?} twice to see all possibilities,
we want @samp{a} which means the author (the from
-header). Now Gnus wants to know which kind of matching we want.
+header). Now Gnus wants to know which kind of matching we want.
Hit either @samp{e} for an exact match or
@samp{s} for substring-match and delete afterwards
everything but the name to score down all authors with the given
-name no matter which email address is used. Now you need to tell
+name no matter which email address is used. Now you need to tell
Gnus when to apply the rule and how long it should last, hit
@samp{p} to apply the rule now and let it last
-forever. If you want to raise the score instead of lowering it say
+forever. If you want to raise the score instead of lowering it say
@samp{I} instead of @samp{L}.
-You can also set up rules by hand. To do this say @samp{V
-f} in summary buffer. Then you are asked for the name
+You can also set up rules by hand. To do this say @samp{V
+f} in summary buffer. Then you are asked for the name
of the score file, it's name.of.group.SCORE for rules valid in
-only one group or all.Score for rules valid in all groups. See the
+only one group or all.Score for rules valid in all groups. See the
Gnus manual for the exact syntax, basically it's one big list
whose elements are lists again. the first element of those lists
is the header to score on, then one more list with what to match,
which score to assign, when to expire the rule and how to do the
-matching. If you find me very interesting, you could add the
+matching. If you find me very interesting, you could add the
following to your all.Score:
@example
@@ -825,14 +825,14 @@ following to your all.Score:
This would add 999 to the score of messages written by me
and 500 to the score of messages which are a (possibly
-indirect) answer to a message written by me. Of course
+indirect) answer to a message written by me. Of course
nobody with a sane mind would do this :-)
-The third alternative is adaptive scoring. This means Gnus
+The third alternative is adaptive scoring. This means Gnus
watches you and tries to find out what you find
interesting and what annoying and sets up rules
-which reflect this. Adaptive scoring can be a huge help
-when reading high traffic groups. If you want to activate
+which reflect this. Adaptive scoring can be a huge help
+when reading high traffic groups. If you want to activate
adaptive scoring say
@example
@@ -852,11 +852,11 @@ set other variables specific for some groups?
While in group buffer move point over the group and hit
@samp{G c}, this opens a buffer where you
-can set options for the group. At the bottom of the buffer
+can set options for the group. At the bottom of the buffer
you'll find an item that allows you to set variables
-locally for the group. To disable threading enter
+locally for the group. To disable threading enter
gnus-show-threads as name of variable and @code{nil} as
-value. Hit button done at the top of the buffer when
+value. Hit button done at the top of the buffer when
you're ready.
@node FAQ 4-11
@@ -868,7 +868,7 @@ those?
@subsubheading Answer
Stop those "Can I ..." questions, the answer is always yes
-in Gnus Country :-). It's a three step process: First we
+in Gnus Country :-). It's a three step process: First we
make faces (specifications of how summary-line shall look
like) for those postings, then we'll give them some
special score and finally we'll tell Gnus to use the new
@@ -879,16 +879,16 @@ faces.
The number of total messages in a group which Gnus
displays in group buffer is by far to high, especially in
-mail groups. Is this a bug?
+mail groups. Is this a bug?
@subsubheading Answer
No, that's a matter of design of Gnus, fixing this would
mean reimplementation of major parts of Gnus'
-back ends. Gnus thinks ``highest-article-number @minus{}
-lowest-article-number = total-number-of-articles''. This
+back ends. Gnus thinks ``highest-article-number @minus{}
+lowest-article-number = total-number-of-articles''. This
works OK for Usenet groups, but if you delete and move
-many messages in mail groups, this fails. To cure the
+many messages in mail groups, this fails. To cure the
symptom, enter the group via @samp{C-u @key{RET}}
(this makes Gnus get all messages), then
hit @samp{M P b} to mark all messages and
@@ -907,9 +907,9 @@ to change it? Perhaps even a three pane display?
@subsubheading Answer
You can control the windows configuration by calling the
-function gnus-add-configuration. The syntax is a bit
+function gnus-add-configuration. The syntax is a bit
complicated but explained very well in the manual node
-"Window Layout". Some popular examples:
+"Window Layout". Some popular examples:
Instead 25% summary 75% article buffer 35% summary and 65%
article (the 1.0 for article means "take the remaining
@@ -951,11 +951,11 @@ I don't like the way the Summary buffer looks, how to tweak it?
@subsubheading Answer
You've got to play around with the variable
-gnus-summary-line-format. Its value is a string of
+gnus-summary-line-format. Its value is a string of
symbols which stand for things like author, date, subject
-etc. A list of the available specifiers can be found in the
+etc. A list of the available specifiers can be found in the
manual node ``Summary Buffer Lines'' and the often forgotten
-node ``Formatting Variables'' and its sub-nodes. There
+node ``Formatting Variables'' and its sub-nodes. There
you'll find useful things like positioning the cursor and
tabulators which allow you a summary in table form, but
sadly hard tabulators are broken in 5.8.8.
@@ -963,7 +963,7 @@ sadly hard tabulators are broken in 5.8.8.
Gnus offers you some very nice new specifiers,
e.g., %B which draws a thread-tree and %&user-date which
gives you a date where the details are dependent of the
-articles age. Here's an example which uses both:
+articles age. Here's an example which uses both:
@example
(setq gnus-summary-line-format ":%U%R %B %s %-60=|%4L |%-20,20f |%&user-date; \n")
@@ -997,19 +997,19 @@ How to split incoming mails in several groups?
Gnus offers two possibilities for splitting mail, the easy
nnmail-split-methods and the more powerful Fancy Mail
-Splitting. I'll only talk about the first one, refer to
+Splitting. I'll only talk about the first one, refer to
the manual, node "Fancy Mail Splitting" for the latter.
The value of nnmail-split-methods is a list, each element
-is a list which stands for a splitting rule. Each rule has
+is a list which stands for a splitting rule. Each rule has
the form "group where matching articles should go to",
"regular expression which has to be matched", the first
-rule which matches wins. The last rule must always be a
+rule which matches wins. The last rule must always be a
general rule (regular expression .*) which denotes where
-articles should go which don't match any other rule. If
+articles should go which don't match any other rule. If
the folder doesn't exist yet, it will be created as soon
as an article lands there. By default the mail will be
-send to all groups whose rules match. If you
+send to all groups whose rules match. If you
don't want that (you probably don't want), say
@example
@@ -1020,11 +1020,11 @@ don't want that (you probably don't want), say
in @file{~/.gnus.el}.
An example might be better than thousand words, so here's
-my nnmail-split-methods. Note that I send duplicates in a
+my nnmail-split-methods. Note that I send duplicates in a
special group and that the default group is spam, since I
filter all mails out which are from some list I'm
subscribed to or which are addressed directly to me
-before. Those rules kill about 80% of the Spam which
+before. Those rules kill about 80% of the Spam which
reaches me (Email addresses are changed to prevent spammers
from using them):
@@ -1089,10 +1089,10 @@ of the variables @code{shr-color-visible-distance-min} and
* FAQ 5-7:: Is there some kind of address-book, so I needn't
remember all those email addresses?
* FAQ 5-8:: Sometimes I see little images at the top of article
- buffer. What's that and how can I send one with my postings,
+ buffer. What's that and how can I send one with my postings,
too?
* FAQ 5-9:: Sometimes I accidentally hit r instead of f in
- newsgroups. Can Gnus warn me, when I'm replying by mail in
+ newsgroups. Can Gnus warn me, when I'm replying by mail in
newsgroups?
* FAQ 5-10:: How to tell Gnus not to generate a sender header?
* FAQ 5-11:: I want Gnus to locally store copies of my send mail and
@@ -1115,18 +1115,18 @@ either in Group or Summary buffer, for a posting, it's
either @samp{a} in Group buffer and
filling the Newsgroups header manually
or @samp{a} in the Summary buffer of the
-group where the posting shall be send to. Replying by mail
+group where the posting shall be send to. Replying by mail
is
@samp{r} if you don't want to cite the
author, or import the cited text manually and
@samp{R} to cite the text of the original
-message. For a follow up to a newsgroup, it's
+message. For a follow up to a newsgroup, it's
@samp{f} and @samp{F}
(analogously to @samp{r} and
@samp{R}).
Enter new headers above the line saying "--text follows
-this line--", enter the text below the line. When ready
+this line--", enter the text below the line. When ready
hit @samp{C-c C-c}, to send the message,
if you want to finish it later hit @samp{C-c
C-d} to save it in the drafts group, where you
@@ -1189,7 +1189,7 @@ organization, address, name or body. The attribute name
can also be a string. In that case, this will be used as
a header name, and the value will be inserted in the
headers of the article; if the value is @code{nil}, the header
-name will be removed. You can also say (eval (foo bar)),
+name will be removed. You can also say (eval (foo bar)),
then the function foo will be evaluated with argument bar
and the result will be thrown away.
@@ -1200,8 +1200,8 @@ Can I set things like From, Signature etc group based on the group I post too?
@subsubheading Answer
-That's the strength of posting styles. Before, we used ".*"
-to set the default for all groups. You can use a regexp
+That's the strength of posting styles. Before, we used ".*"
+to set the default for all groups. You can use a regexp
like "^gmane" and the following settings are only applied
to postings you send to the gmane hierarchy, use
".*binaries" instead and they will be applied to postings
@@ -1210,7 +1210,7 @@ name etc.
You can instead of specifying a regexp specify a function
which is evaluated, only if it returns true, the
-corresponding settings take effect. Two interesting
+corresponding settings take effect. Two interesting
candidates for this are message-news-p which returns t if
the current Group is a newsgroup and the corresponding
message-mail-p.
@@ -1220,7 +1220,7 @@ the example below, when I post to
gmane.mail.spam.spamassassin.general, the settings under
".*" are applied and the settings under message-news-p and
those under "^gmane" and those under
-"^gmane\\.mail\\.spam\\.spamassassin\\.general$". Because
+"^gmane\\.mail\\.spam\\.spamassassin\\.general$". Because
of this put general settings at the top and specific ones
at the bottom.
@@ -1302,7 +1302,7 @@ Yes, say something like
@end example
@noindent
-in @file{~/.gnus.el}. Change "^de\\." and "deutsch8" to something
+in @file{~/.gnus.el}. Change "^de\\." and "deutsch8" to something
that suits your needs.
@node FAQ 5-7
@@ -1324,13 +1324,13 @@ alias al "Al <al@@english-heritage.invalid>"
Then typing your alias (followed by a space or punctuation
character) on a To: or Cc: line in the message buffer will
-cause Gnus to insert the full address for you. See the
+cause Gnus to insert the full address for you. See the
node "Mail Aliases" in Message (not Gnus) manual for
details.
However, what you really want is the Insidious Big Brother
-Database bbdb. Get it from
-@uref{http://bbdb.sourceforge.net/, bbdb's website}.
+Database bbdb. Get it from
+@uref{https://bbdb.sourceforge.net/, bbdb's website}.
Now place the following in @file{~/.gnus.el}, to activate bbdb for Gnus:
@example
@@ -1358,14 +1358,14 @@ place them in ~/.emacs:
@end example
@noindent
-Now you should be ready to go. Say @samp{M-x bbdb @key{RET}
+Now you should be ready to go. Say @samp{M-x bbdb @key{RET}
@key{RET}} to open a bbdb buffer showing all
-entries. Say @samp{c} to create a new
+entries. Say @samp{c} to create a new
entry, @samp{b} to search your BBDB and
@samp{C-o} to add a new field to an
-entry. If you want to add a sender to the BBDB you can
+entry. If you want to add a sender to the BBDB you can
also just hit @kbd{:} on the posting in the summary buffer and
-you are done. When you now compose a new mail,
+you are done. When you now compose a new mail,
hit @samp{TAB} to cycle through know
recipients.
@@ -1373,18 +1373,18 @@ recipients.
@subsubheading Question 5.8
Sometimes I see little images at the top of article
-buffer. What's that and how can I send one with my
+buffer. What's that and how can I send one with my
postings, too?
@subsubheading Answer
-Those images are called X-Faces. They are 48*48 pixel b/w
-pictures, encoded in a header line. If you want to include
+Those images are called X-Faces. They are 48*48 pixel b/w
+pictures, encoded in a header line. If you want to include
one in your posts, you've got to convert some image to a
-X-Face. So fire up some image manipulation program (say
+X-Face. So fire up some image manipulation program (say
Gimp), open the image you want to include, cut out the
relevant part, reduce color depth to 1 bit, resize to
-48*48 and save as bitmap. Now you should get the compface
+48*48 and save as bitmap. Now you should get the compface
package from
@uref{ftp://ftp.cs.indiana.edu/pub/faces/, this site}.
and create the actual X-face by saying
@@ -1424,7 +1424,7 @@ to @code{gnus-posting-styles}.
@subsubheading Question 5.9
Sometimes I accidentally hit r instead of f in
-newsgroups. Can Gnus warn me, when I'm replying by mail in
+newsgroups. Can Gnus warn me, when I'm replying by mail in
newsgroups?
@subsubheading Answer
@@ -1454,7 +1454,7 @@ news, how to do it?
@subsubheading Answer
You must set the variable gnus-message-archive-group to do
-this. You can set it to a string giving the name of the
+this. You can set it to a string giving the name of the
group where the copies shall go or like in the example
below use a function which is evaluated and which returns
the group to use.
@@ -1491,8 +1491,8 @@ aren't they and how to fix it?
@subsubheading Answer
The message-ID is a unique identifier for messages you
-send. To make it unique, Gnus need to know which machine
-name to put after the "@@". If the name of the machine
+send. To make it unique, Gnus need to know which machine
+name to put after the "@@". If the name of the machine
where Gnus is running isn't suitable (it probably isn't
at most private machines) you can tell Gnus what to use
by saying:
@@ -1519,7 +1519,7 @@ instead (works for newer versions as well):
If you have no idea what to insert for
"yourmachine.yourdomain.tld", you've got several
-choices. You can either ask your provider if he allows
+choices. You can either ask your provider if he allows
you to use something like
yourUserName.userfqdn.provider.net, or you can use
somethingUnique.yourdomain.tld if you own the domain
@@ -1556,7 +1556,7 @@ correctly by sending yourself a Mail and looking at the Message-ID.
* FAQ 6-3:: How to search for a specific message?
* FAQ 6-4:: How to get rid of old unwanted mail?
* FAQ 6-5:: I want that all read messages are expired (at least in
- some groups). How to do it?
+ some groups). How to do it?
* FAQ 6-6:: I don't want expiration to delete my mails but to move
them to another group.
@end menu
@@ -1569,16 +1569,16 @@ How to import my old mail into Gnus?
@subsubheading Answer
The easiest way is to tell your old mail program to
-export the messages in mbox format. Most Unix mailers
+export the messages in mbox format. Most Unix mailers
are able to do this, if you come from the MS Windows
world, you may find tools at
@uref{https://sourceforge.net/projects/mbx2mbox/}.
-Now you've got to import this mbox file into Gnus. To do
+Now you've got to import this mbox file into Gnus. To do
this, create a nndoc group based on the mbox file by
saying @samp{G f /path/file.mbox @key{RET}} in
-Group buffer. You now have read-only access to your
-mail. If you want to import the messages to your normal
+Group buffer. You now have read-only access to your
+mail. If you want to import the messages to your normal
Gnus mail groups hierarchy, enter the nndoc group you've
just created by saying @samp{C-u @key{RET}}
(thus making sure all messages are retrieved), mark all
@@ -1597,8 +1597,8 @@ How to archive interesting messages?
If you stumble across an interesting message, say in
gnu.emacs.gnus and want to archive it there are several
-solutions. The first and easiest is to save it to a file
-by saying @samp{O f}. However, wouldn't
+solutions. The first and easiest is to save it to a file
+by saying @samp{O f}. However, wouldn't
it be much more convenient to have more direct access to
the archived message from Gnus? If you say yes, put this
snippet by Frank Haun <pille3003@@fhaun.de> in
@@ -1607,7 +1607,7 @@ snippet by Frank Haun <pille3003@@fhaun.de> in
@example
(defun my-archive-article (&optional n)
"Copies one or more article(s) to a corresponding `nnml:' group, e.g.,
-`gnus.ding' goes to `nnml:1.gnus.ding'. And `nnml:List-gnus.ding' goes
+`gnus.ding' goes to `nnml:1.gnus.ding'. And `nnml:List-gnus.ding' goes
to `nnml:1.List-gnus-ding'.
Use process marks or mark a region in the summary buffer to archive
@@ -1644,7 +1644,7 @@ How to search for a specific message?
@subsubheading Answer
-There are several ways for this, too. For a posting from
+There are several ways for this, too. For a posting from
a Usenet group the easiest solution is probably to ask
@uref{https://groups.google.com, groups.google.com},
if you found the posting there, tell Google to display
@@ -1659,9 +1659,9 @@ Another idea which works for both mail and news groups
is to enter the group where the message you are
searching is and use the standard Emacs search
@samp{C-s}, it's smart enough to look at
-articles in collapsed threads, too. If you want to
+articles in collapsed threads, too. If you want to
search bodies, too try @samp{M-s}
-instead. Further on there are the
+instead. Further on there are the
gnus-summary-limit-to-foo functions, which can help you,
too.
@@ -1675,17 +1675,17 @@ How to get rid of old unwanted mail?
You can of course just mark the mail you don't need
anymore by saying @samp{#} with point
over the mail and then say @samp{B @key{DEL}}
-to get rid of them forever. You could also instead of
+to get rid of them forever. You could also instead of
actually deleting them, send them to a junk-group by
saying @samp{B m nnml:trash-bin} which
you clear from time to time, but both are not the intended
way in Gnus.
In Gnus, we let mail expire like news expires on a news
-server. That means you tell Gnus the message is
+server. That means you tell Gnus the message is
expirable (you tell Gnus "I don't need this mail
anymore") by saying @samp{E} with point
-over the mail in summary buffer. Now when you leave the
+over the mail in summary buffer. Now when you leave the
group, Gnus looks at all messages which you marked as
expirable before and if they are old enough (default is
older than a week) they are deleted.
@@ -1694,24 +1694,24 @@ older than a week) they are deleted.
@subsubheading Question 6.5
I want that all read messages are expired (at least in
-some groups). How to do it?
+some groups). How to do it?
@subsubheading Answer
If you want all read messages to be expired (e.g., in
mailing lists where there's an online archive), you've
got two choices: auto-expire and
-total-expire. Auto-expire means, that every article
+total-expire. Auto-expire means, that every article
which has no marks set and is selected for reading is
marked as expirable, Gnus hits @samp{E}
-for you every time you read a message. Total-expire
+for you every time you read a message. Total-expire
follows a slightly different approach, here all article
where the read mark is set are expirable.
To activate auto-expire, include auto-expire in the
Group parameters for the group. (Hit @samp{G
c} in summary buffer with point over the
-group to change group parameters). For total-expire add
+group to change group parameters). For total-expire add
total-expire to the group-parameters.
Which method you choose is merely a matter of taste:
@@ -1753,7 +1753,7 @@ variables specific for some groups?")
* FAQ 7-1:: I don't have a permanent connection to the net, how can I
minimize the time I've got to be connected?
* FAQ 7-2:: So what was this thing about the Agent?
-* FAQ 7-3:: I want to store article bodies on disk, too. How to do
+* FAQ 7-3:: I want to store article bodies on disk, too. How to do
it?
* FAQ 7-4:: How to tell Gnus not to try to send mails / postings
while I'm offline?
@@ -1782,15 +1782,15 @@ when you're online.
Let's talk about Unix systems first: For the news part,
the easiest solution is a small nntp server like
@uref{https://www.leafnode.org/, Leafnode} or
-@uref{http://patrik.iki.fi/sn/, sn},
+@uref{https://patrik.iki.fi/sn/, sn},
of course you can also install a full featured news
server like
@uref{https://www.isc.org/othersoftware/, inn}.
Then you want to fetch your Mail, popular choices
are @uref{https://www.fetchmail.info/, fetchmail}
-and @uref{http://pyropus.ca/software/getmail/, getmail}.
+and @uref{https://pyropus.ca/software/getmail/, getmail}.
You should tell those to write the mail to your disk and
-Gnus to read it from there. Last but not least the mail
+Gnus to read it from there. Last but not least the mail
sending part: This can be done with every MTA like
@uref{https://www.proofpoint.com/us/open-source-email-solution, sendmail} or
@uref{https://www.exim.org/, exim}.
@@ -1800,7 +1800,7 @@ On windows boxes I'd vote for
it's a small freeware, open-source program which fetches
your mail and news from remote servers and offers them
to Gnus (or any other mail and/or news reader) via nntp
-respectively POP3 or IMAP@. It also includes a smtp
+respectively POP3 or IMAP@. It also includes a smtp
server for receiving mails from Gnus.
@node FAQ 7-2
@@ -1812,7 +1812,7 @@ So what was this thing about the Agent?
The Gnus agent is part of Gnus, it allows you to fetch
mail and news and store them on disk for reading them
-later when you're offline. It kind of mimics offline
+later when you're offline. It kind of mimics offline
newsreaders like Forte Agent. It is enabled by default.
You've got to select the servers whose groups can be
@@ -1831,7 +1831,7 @@ there the next time you enter the group.
@node FAQ 7-3
@subsubheading Question 7.3
-I want to store article bodies on disk, too. How to do it?
+I want to store article bodies on disk, too. How to do it?
@subsubheading Answer
@@ -1839,16 +1839,16 @@ You can tell the agent to automatically fetch the bodies
of articles which fulfill certain predicates, this is
done in a special buffer which can be reached by
saying @samp{J c} in group
-buffer. Please refer to the documentation for
+buffer. Please refer to the documentation for
information which predicates are possible and how
exactly to do it.
Further on you can tell the agent manually which
-articles to store on disk. There are two ways to do
+articles to store on disk. There are two ways to do
this: Number one: In the summary buffer, process mark a
set of articles that shall be stored in the agent by
saying @samp{#} with point over the
-article and then type @samp{J s}. The
+article and then type @samp{J s}. The
other possibility is to set, again in the summary
buffer, downloadable (%) marks for the articles you
want by typing @samp{@@} with point over
@@ -1873,11 +1873,11 @@ while I'm offline?
All you've got to do is to tell Gnus when you are online
(plugged) and when you are offline (unplugged), the rest
-works automatically. You can toggle plugged/unplugged
+works automatically. You can toggle plugged/unplugged
state by saying @samp{J j} in group
-buffer. To start Gnus unplugged say @samp{M-x
+buffer. To start Gnus unplugged say @samp{M-x
gnus-unplugged} instead of
-@samp{M-x gnus}. Note that for this to
+@samp{M-x gnus}. Note that for this to
work, the agent must be active.
@node FAQ 8 - Getting help
@@ -1903,10 +1903,10 @@ How to find information and help inside Emacs?
The first stop should be the Gnus manual (Say
@samp{C-h i d m Gnus @key{RET}} to start the
Gnus manual, then walk through the menus or do a
-full-text search with @samp{s}). Then
+full-text search with @samp{s}). Then
there are the general Emacs help commands starting with
C-h, type @samp{C-h ? ?} to get a list
-of all available help commands and their meaning. Finally
+of all available help commands and their meaning. Finally
@samp{M-x apropos-command} lets you
search through all available functions and @samp{M-x
apropos} searches the bound variables.
@@ -1999,10 +1999,10 @@ active file, see the node "The Active File" in the Gnus
manual for things you might try to speed the process up.
An other idea would be to byte compile your @file{~/.gnus.el} (say
@samp{M-x byte-compile-file @key{RET} ~/.gnus.el
-@key{RET}} to do it). Finally, if you have require
+@key{RET}} to do it). Finally, if you have require
statements in your .gnus, you could replace them with
@code{with-eval-after-load}, which loads the stuff not at startup
-time, but when it's needed. Say you've got this in your
+time, but when it's needed. Say you've got this in your
@file{~/.gnus.el}:
@example
@@ -2011,7 +2011,7 @@ time, but when it's needed. Say you've got this in your
@end example
@noindent
-then as soon as you start Gnus, message.el is loaded. If
+then as soon as you start Gnus, message.el is loaded. If
you replace it with
@example
@@ -2052,7 +2052,7 @@ Sending mail becomes slower and slower, what's up?
The reason could be that you told Gnus to archive the
messages you wrote by setting
-gnus-message-archive-group. Try to use a nnml group
+gnus-message-archive-group. Try to use a nnml group
instead of an archive group, this should bring you back
to normal speed.
@@ -2063,7 +2063,7 @@ to normal speed.
@item ~/.gnus.el
When the term @file{~/.gnus.el} is used it just means your Gnus
-configuration file. You might as well call it @file{~/.gnus} or
+configuration file. You might as well call it @file{~/.gnus} or
specify another name.
@item Back End
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index b1331e79bf4..4180b9be108 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -8045,7 +8045,7 @@ to a string containing the default command and options (default
@findex gnus-summary-muttprint
@vindex gnus-summary-muttprint-program
Save the current article into muttprint. That is, print it using the
-external program @uref{http://muttprint.sourceforge.net/,
+external program @uref{https://muttprint.sourceforge.net/,
Muttprint}. The program name and options to use is controlled by the
variable @code{gnus-summary-muttprint-program}.
(@code{gnus-summary-muttprint}).
@@ -9343,7 +9343,7 @@ Use Gnus rendered based on w3m.
Use @uref{http://emacs-w3m.namazu.org/, emacs-w3m}.
@item w3m-standalone
-Use @uref{http://w3m.sourceforge.net/, w3m}.
+Use @uref{https://w3m.sourceforge.net/, w3m}.
@item links
Use @uref{http://links.twibright.com/, Links}.
@@ -13602,7 +13602,7 @@ Here's the method for a public spool:
If you are behind a firewall and only have access to the @acronym{NNTP}
server from the firewall machine, you can instruct Gnus to @code{rlogin}
on the firewall machine and connect with
-@uref{http://netcat.sourceforge.net/, netcat} from there to the
+@uref{https://netcat.sourceforge.net/, netcat} from there to the
@acronym{NNTP} server.
Doing this can be rather fiddly, but your virtual server definition
should probably look something like this:
@@ -23794,7 +23794,7 @@ On a GNU/Linux system, the @code{display} program is included in the
ImageMagick package. For external conversion programs look for packages
with names like @code{netpbm}, @code{libgr-progs} and @code{compface}.
On Windows, you may use the packages @code{netpbm} and @code{compface}
-from @url{http://gnuwin32.sourceforge.net}. You need to add the
+from @url{https://gnuwin32.sourceforge.net}. You need to add the
@code{bin} directory to your @code{PATH} environment variable.
@c In fact only the following DLLs and binaries seem to be required:
@c compface1.dll uncompface.exe libnetpbm10.dll icontopbm.exe
diff --git a/doc/misc/mh-e.texi b/doc/misc/mh-e.texi
index 6aa2cf290da..1a80c62edba 100644
--- a/doc/misc/mh-e.texi
+++ b/doc/misc/mh-e.texi
@@ -3082,7 +3082,7 @@ retracted---without question@footnote{In previous versions of MH-E,
this option suppressed the confirmation in @code{mh-kill-folder}.
Since this kept most users from setting this option,
@code{mh-kill-folder} was modified in version 6.0 to always ask for
-confirmation subject to @code{mh-kill-folder-suppress-prompt-hook}.
+confirmation subject to @code{mh-kill-folder-suppress-prompt-functions}.
@xref{Folders}.}.
@cindex MH-Folder mode
@@ -3364,7 +3364,7 @@ Hook run by q before quitting MH-E (default: @code{nil}).
Hook run by @code{mh-folder-mode} when visiting a new folder (default:
@code{nil}).
@c -------------------------
-@item mh-kill-folder-suppress-prompt-hook
+@item mh-kill-folder-suppress-prompt-functions
Abnormal hook run at the beginning of @code{mh-kill-folder} (default:
@code{'mh-search-p}).
@c -------------------------
@@ -7540,8 +7540,8 @@ Allowlisted message face
@cindex spam filters, bogofilter
MH-E depends on @uref{https://spamassassin.apache.org/, SpamAssassin},
-@uref{http://bogofilter.sourceforge.net/, bogofilter}, or
-@uref{http://spamprobe.sourceforge.net/, SpamProbe} to throw the dreck
+@uref{https://bogofilter.sourceforge.net/, bogofilter}, or
+@uref{https://spamprobe.sourceforge.net/, SpamProbe} to throw the dreck
away. This chapter describes briefly how to configure these programs
to work well with MH-E and how to use MH-E's interface that provides
continuing education for these programs.
@@ -7721,7 +7721,7 @@ done by adding the following to your @file{crontab}:
Bogofilter is a Bayesian spam filtering program. Get it from your
local distribution or from the
-@uref{http://bogofilter.sourceforge.net/, bogofilter web site}.
+@uref{https://bogofilter.sourceforge.net/, bogofilter web site}.
Bogofilter is taught by running:
@@ -7791,7 +7791,7 @@ bogofilter.
@cindex spam filters, SpamProbe
SpamProbe is a Bayesian spam filtering program. Get it from your local
-distribution or from the @uref{http://spamprobe.sourceforge.net,
+distribution or from the @uref{https://spamprobe.sourceforge.net,
SpamProbe web site}.
To use SpamProbe, add the following recipes to @file{~/.procmailrc}:
@@ -8633,7 +8633,7 @@ via SourceForge (@pxref{Bug Reports}).
@cindex FAQ
@cindex MH FAQ
-The article @uref{http://www.newt.com/faq/mh.html, @cite{MH Frequently
+The article @uref{https://www.newt.com/faq/mh.html, @cite{MH Frequently
Asked Questions (FAQ) with Answers}} appears monthly in the newsgroup
@samp{comp.mail.mh}. While very little is there that deals with MH-E
specifically, there is an incredible wealth of material about MH
diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org
index 1b4bf88a0cc..2680fe9eb51 100644
--- a/doc/misc/modus-themes.org
+++ b/doc/misc/modus-themes.org
@@ -4,9 +4,9 @@
#+language: en
#+options: ':t toc:nil author:t email:t num:t
#+startup: content
-#+macro: stable-version 2.6.0
-#+macro: release-date 2022-08-19
-#+macro: development-version 2.7.0-dev
+#+macro: stable-version 2.7.0
+#+macro: release-date 2022-10-01
+#+macro: development-version 2.8.0-dev
#+macro: file @@texinfo:@file{@@$1@@texinfo:}@@
#+macro: space @@texinfo:@: @@
#+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@
@@ -3902,6 +3902,7 @@ package:
(use-package circadian ; you need to install this
:ensure
:after solar
+ :config
(setq circadian-themes '((:sunrise . modus-operandi)
(:sunset . modus-vivendi)))
(circadian-setup))
@@ -4514,6 +4515,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ calendar and diary
+ calfw
+ calibredb
++ centaur-tabs
+ cfrs
+ change-log and log-view (such as ~vc-print-log~, ~vc-print-root-log~)
+ chart
@@ -4533,6 +4535,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ counsel-css
+ cov
+ cperl-mode
++ crontab-mode
+ css-mode
+ csv-mode
+ ctrlf
@@ -4705,6 +4708,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ powerline
+ powerline-evil
+ prism ([[#h:a94272e0-99da-4149-9e80-11a7e67a2cf2][Note for prism.el]])
++ prescient
+ proced
+ prodigy
+ pulse
@@ -4738,6 +4742,7 @@ have lots of extensions, so the "full support" may not be 100% true…
+ smerge
+ spaceline
+ speedbar
++ spell-fu
+ stripes
+ suggest
+ switch-window
@@ -5596,6 +5601,32 @@ those buttons. Disabling the logo fixes the problem:
(setq notmuch-show-logo nil)
#+end_src
+** Note on goto-address-mode faces
+:PROPERTIES:
+:CUSTOM_ID: h:2d74236a-e41c-4616-8735-75f949a67334
+:END:
+
+The built-in ~goto-address-mode~ uses heuristics to identify URLs and
+email addresses in the current buffer. It then applies a face to them
+to change their style. Some packages, such as =notmuch=, use this
+minor-mode automatically.
+
+The faces are not declared with ~defface~, meaning that it is better
+that the theme does not modify them. The user is thus encouraged to
+consider including (or equivalent) this in their setup:
+
+#+begin_src emacs-lisp
+(setq goto-address-url-face 'link
+ goto-address-url-mouse-face 'highlight
+ goto-address-mail-face 'link
+ goto-address-mail-mouse-face 'highlight)
+#+end_src
+
+My personal preference is to set ~goto-address-mail-face~ to nil, as
+it otherwise adds too much visual noise to the buffer (email addresses
+stand out more, due to the use of the uncommon =@= character but also
+because they are often enclosed in angled brackets).
+
* Frequently Asked Questions
:properties:
:custom_id: h:b3384767-30d3-4484-ba7f-081729f03a47
@@ -5868,11 +5899,11 @@ usability beyond matters of color---they would be making a
not-so-obvious error of treating different cases as if they were the
same.
-The Modus themes prioritise "thematic consistency" over abstract harmony
+The Modus themes prioritize "thematic consistency" over abstract harmony
or regularity among their applicable colors. In concrete terms, we do
not claim that, say, our yellows are the best complements for our blues
because we generally avoid using complementary colors side-by-side, so
-it is wrong to optimise for a decontextualised blue+yellow combination.
+it is wrong to optimize for a decontextualised blue+yellow combination.
Not to imply that our colors do not work well together because they do,
just to clarify that consistency of context is what themes must strive
for, and that requires widening the scope of the design beyond the
@@ -6072,42 +6103,44 @@ The Modus themes are a collective effort. Every bit of work matters.
+ Author/maintainer :: Protesilaos Stavrou.
+ Contributions to code or documentation :: Alex Griffin, Anders
- Johansson, Basil L.{{{space()}}} Contovounesios, Björn Lindström,
- Carlo Zancanaro, Christian Tietze, Daniel Mendler, Eli Zaretskii,
- Fritz Grabo, Illia Ostapyshyn, Kévin Le Gouguec, Kostadin Ninev,
- Madhavan Krishnan, Manuel Giraud, Markus Beppler, Matthew Stevenson,
- Mauro Aranda, Nicolas De Jaeghere, Paul David, Philip Kaludercic,
- Pierre Téchoueyres, Rudolf Adamkovič, Stephen Gildea, Shreyas Ragavan,
- Stefan Kangas, Utkarsh Singh, Vincent Murphy, Xinglu Chen, Yuanchen
- Xie.
+ Johansson, Antonio Ruiz, Basil L.{{{space()}}} Contovounesios, Björn
+ Lindström, Carlo Zancanaro, Christian Tietze, Daniel Mendler, Eli
+ Zaretskii, Fritz Grabo, Illia Ostapyshyn, Kévin Le Gouguec, Koen van
+ Greevenbroek, Kostadin Ninev, Madhavan Krishnan, Manuel Giraud,
+ Markus Beppler, Matthew Stevenson, Mauro Aranda, Nicolas De
+ Jaeghere, Paul David, Philip Kaludercic, Pierre Téchoueyres, Rudolf
+ Adamkovič, Stephen Gildea, Shreyas Ragavan, Stefan Kangas, Utkarsh
+ Singh, Vincent Murphy, Xinglu Chen, Yuanchen Xie, okamsn.
+ Ideas and user feedback :: Aaron Jensen, Adam Porter, Adam Spiers,
- Adrian Manea, Alex Griffin, Alex Koen, Alex Peitsinis, Alexey Shmalko,
- Alok Singh, Anders Johansson, André Alexandre Gomes, Andrew Tropin,
- Antonio Hernández Blas, Arif Rezai, Augusto Stoffel, Basil
+ Adrian Manea, Alex Griffin, Alex Koen, Alex Peitsinis, Alexey
+ Shmalko, Alok Singh, Anders Johansson, André Alexandre Gomes, Andrew
+ Tropin, Antonio Hernández Blas, Arif Rezai, Augusto Stoffel, Basil
L.{{{space()}}} Contovounesios, Burgess Chang, Christian Tietze,
- Christopher Dimech, Christopher League, Damien Cassou, Daniel Mendler,
- Dario Gjorgjevski, David Edmondson, Davor Rotim, Divan Santana, Eliraz
- Kedmi, Emanuele Michele Alberto Monterosso, Farasha Euker, Feng Shu,
- Gautier Ponsinet, Gerry Agbobada, Gianluca Recchia, Gonçalo Marrafa,
- Guilherme Semente, Gustavo Barros, Hörmetjan Yiltiz, Ilja Kocken, Iris
- Garcia, Ivan Popovych, Jeremy Friesen, Jerry Zhang, Johannes Grødem,
- John Haman, Jonas Collberg, Jorge Morais, Joshua O'Connor, Julio
- C. Villasante, Kenta Usami, Kevin Fleming, Kévin Le Gouguec, Kostadin
- Ninev, Len Trigg, Lennart C. Karssen, Magne Hov, Manuel Uberti, Mark
- Bestley, Mark Burton, Markus Beppler, Matt Armstrong, Mauro Aranda,
- Maxime Tréca, Michael Goldenberg, Morgan Smith, Morgan Willcock,
- Murilo Pereira, Nicky van Foreest, Nicolas De Jaeghere, Paul Poloskov,
- Pengji Zhang, Pete Kazmier, Peter Wu, Philip Kaludercic, Pierre
- Téchoueyres, Przemysław Kryger, Robert Hepple, Roman Rudakov, Ryan
- Phillips, Rytis Paškauskas, Rudolf Adamkovič, Sam Kleinman, Samuel
- Culpepper, Saša Janiška, Shreyas Ragavan, Simon Pugnet, Tassilo Horn,
- Thibaut Verron, Thomas Heartman, Togan Muftuoglu, Tony Zorman, Trey
- Merkley, Tomasz Hołubowicz, Toon Claes, Uri Sharf, Utkarsh Singh,
- Vincent Foley. As well as users: Ben, CsBigDataHub1, Emacs Contrib,
- Eugene, Fourchaux, Fredrik, Moesasji, Nick, Summer Emacs, TheBlob42,
- Trey, bepolymathe, bit9tream, derek-upham, doolio, fleimgruber,
- gitrj95, iSeeU, jixiuf, okamsn, pRot0ta1p.
+ Christopher Dimech, Christopher League, Damien Cassou, Daniel
+ Mendler, Dario Gjorgjevski, David Edmondson, Davor Rotim, Divan
+ Santana, Eliraz Kedmi, Emanuele Michele Alberto Monterosso, Farasha
+ Euker, Feng Shu, Gautier Ponsinet, Gerry Agbobada, Gianluca Recchia,
+ Gonçalo Marrafa, Guilherme Semente, Gustavo Barros, Hörmetjan
+ Yiltiz, Ilja Kocken, Iris Garcia, Ivan Popovych, Jeremy Friesen,
+ Jerry Zhang, Johannes Grødem, John Haman, Jonas Collberg, Jorge
+ Morais, Joshua O'Connor, Julio C. Villasante, Kenta Usami, Kevin
+ Fleming, Kévin Le Gouguec, Kostadin Ninev, Len Trigg, Lennart
+ C. Karssen, Luis Miguel Castañeda, Magne Hov, Manuel Uberti, Mark
+ Bestley, Mark Burton, Mark Simpson, Markus Beppler, Matt Armstrong,
+ Mauro Aranda, Maxime Tréca, Michael Goldenberg, Morgan Smith, Morgan
+ Willcock, Murilo Pereira, Nicky van Foreest, Nicolas De Jaeghere,
+ Paul Poloskov, Pengji Zhang, Pete Kazmier, Peter Wu, Philip
+ Kaludercic, Pierre Téchoueyres, Przemysław Kryger, Robert Hepple,
+ Roman Rudakov, Ryan Phillips, Rytis Paškauskas, Rudolf Adamkovič,
+ Sam Kleinman, Samuel Culpepper, Saša Janiška, Shreyas Ragavan, Simon
+ Pugnet, Tassilo Horn, Thibaut Verron, Thomas Heartman, Togan
+ Muftuoglu, Tony Zorman, Trey Merkley, Tomasz Hołubowicz, Toon Claes,
+ Uri Sharf, Utkarsh Singh, Vincent Foley. As well as users: Ben,
+ CsBigDataHub1, Emacs Contrib, Eugene, Fourchaux, Fredrik, Moesasji,
+ Nick, Summer Emacs, TheBlob42, Trey, bepolymathe, bit9tream,
+ derek-upham, doolio, fleimgruber, gitrj95, iSeeU, jixiuf, okamsn,
+ pRot0ta1p.
+ Packaging :: Basil L.{{{space()}}} Contovounesios, Eli Zaretskii,
Glenn Morris, Mauro Aranda, Richard Stallman, Stefan Kangas (core
diff --git a/doc/misc/org.org b/doc/misc/org.org
index 7971c417a52..ae3ca0b64f3 100644
--- a/doc/misc/org.org
+++ b/doc/misc/org.org
@@ -68,8 +68,8 @@ of Org, as well as additional information, frequently asked questions
[[https://orgmode.org]].
#+cindex: print edition
-An earlier version (7.3) of this manual is available as a [[http://www.network-theory.co.uk/org/manual/][paperback
-book from Network Theory Ltd.]].
+An earlier version (7.3) of this manual was published as a paperback book by
+Network Theory Ltd. in 2010.
** Installation
:PROPERTIES:
@@ -3234,7 +3234,7 @@ options:
| Link Type | Example |
|------------+----------------------------------------------------------|
-| http | =http://staff.science.uva.nl/c.dominik/= |
+| http | =https://staff.science.uva.nl/c.dominik/= |
| https | =https://orgmode.org/= |
| doi | =doi:10.1000/182= |
| file | =file:/home/dominik/images/jupiter.jpg= |
@@ -3567,7 +3567,7 @@ replacement text. Here is an example:
'(("bugzilla" . "http://10.1.2.9/bugzilla/show_bug.cgi?id=")
("Nu Html Checker" . "https://validator.w3.org/nu/?doc=%h")
("duckduckgo" . "https://duckduckgo.com/?q=%s")
- ("omap" . "http://nominatim.openstreetmap.org/search?q=%s&polygon=1")
+ ("omap" . "https://nominatim.openstreetmap.org/search?q=%s&polygon=1")
("ads" . "https://ui.adsabs.harvard.edu/search/q=%20author%3A\"%s\"")))
#+end_src
@@ -3596,7 +3596,7 @@ can define them in the file with
#+cindex: @samp{LINK}, keyword
#+begin_example
-,#+LINK: bugzilla http://10.1.2.9/bugzilla/show_bug.cgi?id=
+,#+LINK: bugzilla https://10.1.2.9/bugzilla/show_bug.cgi?id=
,#+LINK: duckduckgo https://duckduckgo.com/?q=%s
#+end_example
@@ -11042,7 +11042,7 @@ a major LaTeX mode like AUCTeX in order to speed-up insertion of
environments and math templates. Inside Org mode, you can make use of
some of the features of CDLaTeX mode. You need to install
=cdlatex.el= and =texmathp.el= (the latter comes also with AUCTeX)
-using [[https://melpa.org/][MELPA]] with the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Package-Installation.html][Emacs packaging system]] or alternatively from
+from [[https://elpa.nongnu.org/][NonGNU ELPA]] with the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Package-Installation.html][Emacs packaging system]] or alternatively from
[[https://staff.fnwi.uva.nl/c.dominik/Tools/cdlatex/]]. Do not use
CDLaTeX mode itself under Org mode, but use the special version Org
CDLaTeX minor mode that comes as part of Org. Turn it on for the
@@ -13642,7 +13642,7 @@ not have descriptions, such as these links =[[file:img.jpg]]= or
=[[./img.jpg]]=, as direct image insertions in the final PDF output. In
the PDF, they are no longer links but actual images embedded on the
page. The LaTeX export back-end uses =\includegraphics= macro to
-insert the image. But for TikZ (http://sourceforge.net/projects/pgf/)
+insert the image. But for TikZ (https://sourceforge.net/projects/pgf/)
images, the back-end uses an ~\input~ macro wrapped within
a ~tikzpicture~ environment.
@@ -13982,7 +13982,7 @@ some text in German...
#+cindex: Markdown export
The Markdown export back-end, "md", converts an Org file to Markdown
-format, as defined at http://daringfireball.net/projects/markdown/.
+format, as defined at https://daringfireball.net/projects/markdown/.
Since it is built on top of the HTML back-end (see [[*HTML Export]]), it
converts every Org construct not defined in Markdown syntax, such as
@@ -22024,7 +22024,7 @@ a deadline string. See ~org-agenda-entry-types~ on how to set what
planning information is taken into account.
[fn:104] For HTML you need to install Hrvoje Nikšić's =htmlize.el=
-as an Emacs package from MELPA or from [[https://github.com/hniksic/emacs-htmlize][Hrvoje Nikšić's repository]].
+as an Emacs package from [[https://elpa.nongnu.org/][NonGNU ELPA]] or from [[https://github.com/hniksic/emacs-htmlize][Hrvoje Nikšić's repository]].
[fn:105] To create PDF output, the Ghostscript ps2pdf utility must be
installed on the system. Selecting a PDF file also creates the
@@ -22053,7 +22053,7 @@ MathJax are processed. When dvipng, dvisvgm, or ImageMagick suite is
used to create images, any LaTeX environment is handled.
[fn:112] These are respectively available at
-[[http://sourceforge.net/projects/dvipng/]], [[http://dvisvgm.bplaced.net/]]
+[[https://sourceforge.net/projects/dvipng/]], [[http://dvisvgm.bplaced.net/]]
and from the ImageMagick suite. Choose the converter by setting the
variable ~org-preview-latex-default-process~ accordingly.
@@ -22123,9 +22123,9 @@ semantic relevance.
[fn:130] Please note that exported formulas are part of an HTML
document, and that signs such as =<=, =>=, or =&= have special
-meanings. See [[http://docs.mathjax.org/en/latest/tex.html#tex-and-latex-in-html-documents][MathJax TeX and LaTeX support]].
+meanings. See [[https://docs.mathjax.org/en/latest/tex.html#tex-and-latex-in-html-documents][MathJax TeX and LaTeX support]].
-[fn:131] See [[http://docs.mathjax.org/en/latest/tex.html#tex-extensions][TeX and LaTeX extensions]] in the [[http://docs.mathjax.org][MathJax manual]] to learn
+[fn:131] See [[https://docs.mathjax.org/en/latest/tex.html#tex-extensions][TeX and LaTeX extensions]] in the [[https://docs.mathjax.org][MathJax manual]] to learn
about extensions.
[fn:132] If the classes on TODO keywords and tags lead to conflicts,
@@ -22140,14 +22140,14 @@ as latexmk, can select the correct bibliography compiler.
which requires the flag =-shell-escape= to be added to
~org-latex-pdf-process~.
-[fn:135] See [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][Open Document Format for Office Applications
+[fn:135] See [[https://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][Open Document Format for Office Applications
(OpenDocument) Version 1.2]].
[fn:136] See [[http://www.mathtoweb.com/cgi-bin/mathtoweb_home.pl][MathToWeb]].
-[fn:137] See [[http://dlmf.nist.gov/LaTeXML/]].
+[fn:137] See [[https://dlmf.nist.gov/LaTeXML/]].
-[fn:138] [[http://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][OpenDocument-v1.2 Specification]]
+[fn:138] [[https://docs.oasis-open.org/office/v1.2/OpenDocument-v1.2.html][OpenDocument-v1.2 Specification]]
[fn:139] See the =<table:table-template>= element of the
OpenDocument-v1.2 specification.
@@ -22170,7 +22170,7 @@ are not evaluated when they appear in a keyword (see [[*Summary of
In-Buffer Settings]]).
[fn:144] For noweb literate programming details, see
-http://www.cs.tufts.edu/~nr/noweb/.
+https://www.cs.tufts.edu/~nr/noweb/.
[fn:145] For more information, please refer to the commentary section
in =org-tempo.el=.
diff --git a/doc/misc/rcirc.texi b/doc/misc/rcirc.texi
index 8c798d6c33b..307fe55a63f 100644
--- a/doc/misc/rcirc.texi
+++ b/doc/misc/rcirc.texi
@@ -177,7 +177,7 @@ using a different nick. This will prompt you for four things:
@cindex server, connecting
@cindex Libera.Chat network
@item IRC Server
-What server do you want to connect to? All the servers in a particular
+What server do you want to connect to? All the servers in a particular
network are equivalent. Some networks use a round-robin system where
a single server redirects new connections to a random server in the
network. @code{irc.libera.chat} is such a server for the Libera.Chat
@@ -531,7 +531,7 @@ This variable is used for the default nick. It defaults to the login
name returned by @code{user-login-name}.
@example
-(setq rcirc-default-nick "kensanata")
+(setopt rcirc-default-nick "kensanata")
@end example
@item rcirc-default-port
@@ -557,7 +557,7 @@ to the name returned by @code{user-full-name}. If you want to hide
your full name, you might want to set it to some pseudonym.
@example
-(setq rcirc-default-full-name "Curious Minds Want To Know")
+(setopt rcirc-default-full-name "Curious Minds Want To Know")
@end example
@item rcirc-authinfo
@@ -575,10 +575,10 @@ followed by the arguments this method requires.
Here is an example to illustrate how you would set it:
@example
-(setq rcirc-authinfo
- '(("Libera.Chat" nickserv "bob" "p455w0rd")
- ("Libera.Chat" chanserv "bob" "#bobland" "passwd99")
- ("bitlbee" bitlbee "robert" "sekrit")))
+(setopt rcirc-authinfo
+ '(("Libera.Chat" nickserv "bob" "p455w0rd")
+ ("Libera.Chat" chanserv "bob" "#bobland" "passwd99")
+ ("bitlbee" bitlbee "robert" "sekrit")))
@end example
And here are the valid method symbols and the arguments they require:
@@ -821,7 +821,7 @@ You can control which notices get omitted via the
omit away messages:
@example
-(setq rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK" "AWAY"))
+(setopt rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK" "AWAY"))
@end example
@vindex rcirc-omit-threshold
@@ -840,7 +840,7 @@ and @code{NAMES} messages, after reconnecting, you can configure
@code{rcirc-omit-unless-requested} to hide:
@example
-(setq rcirc-omit-unless-requested '("TOPIC" "NAMES"))
+(setopt rcirc-omit-unless-requested '("TOPIC" "NAMES"))
@end example
Now NAMES will only be displayed, after it has been requested via the
@@ -859,6 +859,7 @@ Here are some examples of stuff you can do to configure @code{rcirc}.
* Changing the time stamp format::
* Defining a new command::
* Using rcirc with bouncers::
+* Dealing with Bridge Bots::
@end menu
@node Skipping /away messages using handlers
@@ -933,7 +934,7 @@ Manual}, for details.
how to include the date in the time stamp:
@example
-(setq rcirc-time-format "%Y-%m-%d %H:%M ")
+(setopt rcirc-time-format "%Y-%m-%d %H:%M ")
@end example
@findex rcirc-when
@@ -969,16 +970,16 @@ because @code{rcirc-define-command} is not yet available, and without
@cindex bouncer
Some bouncers multiplex connections to various servers, but have to
-modify nicks and channel names to make this work. The channel
+modify nicks and channel names to make this work. The channel
@code{#emacs} on @code{irc.libera.chat} becomes
@code{#emacs/irc.libera.chat}.
@vindex rcirc-nick-filter
@vindex rcirc-channel-filter
The options @code{rcirc-nick-filter} and @code{rcirc-channel-filter}
-can be used to make this feel more natural. When set to functions,
+can be used to make this feel more natural. When set to functions,
these will be used to change how nicks and channel names are
-displayed. A simple configuration to fix the above example might be:
+displayed. A simple configuration to fix the above example might be:
@smallexample
(defun my/rcirc-remove-suffix (STR)
@@ -988,10 +989,50 @@ displayed. A simple configuration to fix the above example might be:
(substring str 0 (match-beginning 0))
str)))
-(setq rcirc-nick-filter #'my/rcirc-remove-suffix
- rcirc-channel-filter #'local/rcirc-soju-suffix)
+(setopt rcirc-nick-filter #'my/rcirc-remove-suffix
+ rcirc-channel-filter #'local/rcirc-soju-suffix)
@end smallexample
+@node Dealing with Bridge Bots
+@section Dealing with Bridge Bots
+@cindex bridge
+
+It is increasingly common for IRC channels to be ``bridged'' onto
+other networks such as XMPP, Matrix, etc. Sometimes the software does
+a good job at mapping each non-IRC user into an IRC user, but more
+often than not it doesn't. In that case you might receive a message
+like:
+
+@example
+@verbatim
+09:47 <bridge> <john> I am not on IRC
+@end verbatim
+@end example
+
+where @samp{bridge} is a bot responsible for sending messages back and
+forth between networks, and @samp{john} is the user name of someone on
+a different network. Note that the bot indicates this within the
+message (@verb{|<john> I am not on IRC|}) that appears in your chat
+buffer.
+
+@vindex rcirc-bridge-bot-alist
+If this annoys you, the user option @code{rcirc-bridge-bot-alist} may
+be of use. It consists of descriptions of what users are these kinds
+of ``bridge bots'' and how they format their messages. To handle the
+above example, we might set the user option to:
+
+@example
+(setopt rcirc-bridge-bot-alist
+ '(("bridge" . "<\\(.+?\\)>[[:space:]]+")))
+@end example
+
+If there is an entry for the current user, @code{rcirc} will take the
+associated regular expression and try to find a match in the message
+string. If it manages to find anything, the matching expression is
+deleted from the message. The regular expression must contain at
+least one group that will match the user name of the bridged message.
+This will then be used to replace the username of the bridge bot.
+
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include doclicense.texi
diff --git a/doc/misc/remember.texi b/doc/misc/remember.texi
index 9d1fe545d47..80bb6966e2b 100644
--- a/doc/misc/remember.texi
+++ b/doc/misc/remember.texi
@@ -424,13 +424,6 @@ The default priority for remembered mail messages.
@section Saving to an Org Mode file
@cindex org mode, integration
-@ignore
-From org.texi:
-Up to version 6.36 Org used a special setup
-for @file{remember.el}. @file{org-remember.el} is still part of Org mode for
-backward compatibility with existing setups. You can find the documentation
-for org-remember at @url{http://orgmode.org/org-remember.pdf}.
-@end ignore
For instructions on how to integrate Remember with Org Mode,
consult @ref{Capture, , , org}.
diff --git a/doc/misc/semantic.texi b/doc/misc/semantic.texi
index 25ba30d13c9..b23e4c36fe3 100644
--- a/doc/misc/semantic.texi
+++ b/doc/misc/semantic.texi
@@ -82,7 +82,7 @@ hippie-expand, and several other parts of Emacs.
To send bug reports, or participate in discussions about semantic,
use the mailing list cedet-semantic@@sourceforge.net via the URL:
-@url{http://lists.sourceforge.net/lists/listinfo/cedet-semantic}
+@url{https://lists.sourceforge.net/lists/listinfo/cedet-semantic}
@ifnottex
@insertcopying
diff --git a/doc/misc/sieve.texi b/doc/misc/sieve.texi
index df03dd01442..77a393192c2 100644
--- a/doc/misc/sieve.texi
+++ b/doc/misc/sieve.texi
@@ -339,7 +339,7 @@ Indicate which script on the server should be active.
The Emacs Sieve package implements all or parts of a small but
hopefully growing number of RFCs and drafts documents. This chapter
lists the relevant ones. They can all be fetched from
-@uref{http://quimby.gnus.org/notes/}.
+@uref{https://quimby.gnus.org/notes/}.
@table @dfn
diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex
index f86af0db3e5..09f2d28c2f2 100644
--- a/doc/misc/texinfo.tex
+++ b/doc/misc/texinfo.tex
@@ -3,7 +3,7 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2022-08-20.19}
+\def\texinfoversion{2022-09-21.15}
%
% Copyright 1985, 1986, 1988, 1990-2022 Free Software Foundation, Inc.
%
@@ -241,9 +241,6 @@
%
\def\finalout{\overfullrule=0pt }
-\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
-\newdimen\topandbottommargin \topandbottommargin=.75in
-
% Output a mark which sets \thischapter, \thissection and \thiscolor.
% We dump everything together because we only have one kind of mark.
% This works because we only use \botmark / \topmark, not \firstmark.
@@ -317,16 +314,8 @@
\newbox\footlinebox
% When outputting the double column layout for indices, an output routine
-% is run several times, which hides the original value of \topmark. This
-% can lead to a page heading being output and duplicating the chapter heading
-% of the index. Hence, save the contents of \topmark at the beginning of
-% the output routine. The saved contents are valid until we actually
-% \shipout a page.
-%
-% (We used to run a short output routine to actually set \topmark and
-% \firstmark to the right values, but if this was called with an empty page
-% containing whatsits for writing index entries, the whatsits would be thrown
-% away and the index auxiliary file would remain empty.)
+% is run several times, hiding the original value of \topmark. Hence, save
+% \topmark at the beginning.
%
\newtoks\savedtopmark
\newif\iftopmarksaved
@@ -351,15 +340,9 @@
%
\checkchapterpage
%
- % Retrieve the information for the headings from the marks in the page,
- % and call Plain TeX's \makeheadline and \makefootline, which use the
- % values in \headline and \footline.
- %
- % Common context changes for both heading and footing.
- % Do this outside of the \shipout so @code etc. will be expanded in
- % the headline as they should be, not taken literally (outputting ''code).
+ % Make the heading and footing. \makeheadline and \makefootline
+ % use the contents of \headline and \footline.
\def\commonheadfootline{\let\hsize=\txipagewidth \texinfochars}
- %
\ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
\global\setbox\headlinebox = \vbox{\commonheadfootline \makeheadline}%
\ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
@@ -617,21 +600,6 @@
% @? is an end-of-sentence query.
\def\?{?\spacefactor=\endofsentencespacefactor\space}
-% @frenchspacing on|off says whether to put extra space after punctuation.
-%
-\def\onword{on}
-\def\offword{off}
-%
-\parseargdef\frenchspacing{%
- \def\temp{#1}%
- \ifx\temp\onword \plainfrenchspacing
- \else\ifx\temp\offword \plainnonfrenchspacing
- \else
- \errhelp = \EMsimple
- \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
- \fi\fi
-}
-
% @w prevents a word break. Without the \leavevmode, @w at the
% beginning of a paragraph, when TeX is still in vertical mode, would
% produce a whole line of output instead of starting the paragraph.
@@ -2803,14 +2771,22 @@ end
% @var unconditionally uses \sl. This gives consistency for
% parameter names whether they are in @def, @table @code or a
% regular paragraph.
+% To get ttsl font for @var when used in code context, @set txicodevaristt.
% The \null is to reset \spacefactor.
\def\aftersmartic{}
\def\var#1{%
\let\saveaftersmartic = \aftersmartic
\def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
- {\sl #1}\smartitaliccorrection
+ %
+ \ifflagclear{txicodevaristt}%
+ {\def\varnext{{{\sl #1}}\smartitaliccorrection}}%
+ {\def\varnext{\smartslanted{#1}}}%
+ \varnext
}
+% To be removed after next release
+\def\SETtxicodevaristt{}% @set txicodevaristt
+
\let\i=\smartitalic
\let\slanted=\smartslanted
\let\dfn=\smartslanted
@@ -2859,6 +2835,24 @@ end
\catcode`@=\other
\def\endofsentencespacefactor{3000}% default
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\let\frenchspacingsetting\plainnonfrenchspacing % used in output routine
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \let\frenchspacingsetting\plainfrenchspacing
+ \else\ifx\temp\offword \let\frenchspacingsetting\plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
+ \fi\fi
+ \frenchspacingsetting
+}
+
+
% @t, explicit typewriter.
\def\t#1{%
{\tt \defcharsdefault \plainfrenchspacing #1}%
@@ -3450,8 +3444,13 @@ $$%
% Revert to plain's \scriptsize, which is 7pt.
\count255=\the\fam $\fam\count255 \scriptstyle A$%
\else
- % For 11pt, we can use our lllsize.
- \switchtolllsize A%
+ \ifx\curfontsize\smallword
+ % For footnotes and indices
+ \count255=\the\fam $\fam\count255 \scriptstyle A$%
+ \else
+ % For 11pt, we can use our lllsize.
+ \switchtolllsize A%
+ \fi
\fi
}%
\vss
@@ -3459,6 +3458,7 @@ $$%
\kern-.15em
\TeX
}
+\def\smallword{small}
% Some math mode symbols. Define \ensuremath to switch into math mode
% unless we are already there. Expansion tricks may not be needed here,
@@ -3829,15 +3829,16 @@ $$%
\newtoks\oddfootline % footline on odd pages
% Now make \makeheadline and \makefootline in Plain TeX use those variables
-\headline={{\textfonts\rm
+\headline={{\textfonts\rm\frenchspacingsetting
\ifchapterpage
\ifodd\pageno\the\oddchapheadline\else\the\evenchapheadline\fi
\else
\ifodd\pageno\the\oddheadline\else\the\evenheadline\fi
\fi}}
-\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
- \else \the\evenfootline \fi}\HEADINGShook}
+\footline={{\textfonts\rm\frenchspacingsetting
+ \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}%
+ \HEADINGShook}
\let\HEADINGShook=\relax
% Commands to set those variables.
@@ -3963,7 +3964,7 @@ $$%
\global\oddfootline={\hfil}
\global\evenheadline={\line{\folio\hfil\thistitle}}
\global\oddheadline={\line{\thischapter\hfil\folio}}
-\global\evenchapheadline={\line{\folio\hfil}}
+\global\evenchapheadline={\line{\folio\hfil\thistitle}}
\global\oddchapheadline={\line{\hfil\folio}}
\global\let\contentsalignmacro = \chapoddpage
}
@@ -4351,8 +4352,7 @@ $$%
% undo it ourselves.
\def\headitemfont{\b}% for people to use in the template row; not changeable
\def\headitem{%
- \checkenv\multitable
- \crcr
+ \crcr % must appear first
\gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings
\global\everytab={\bf}% can't use \headitemfont since the parsing differs
\the\everytab % for the first item
@@ -6755,6 +6755,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\ifnum\romancount=0 \global\romancount=\pagecount \fi
}
+% \raggedbottom in plain.tex hardcodes \topskip so override it
+\catcode`\@=11
+\def\raggedbottom{\advance\topskip by 0pt plus60pt \r@ggedbottomtrue}
+\catcode`\@=\other
+
% redefined for the two-volume lispref. We always output on
% \jobname.toc even if this is redefined.
%
@@ -7115,7 +7120,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% collide with the section heading.
\ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
%
- \setbox\groupbox=\vbox\bgroup
+ \setbox\groupbox=\vtop\bgroup
\baselineskip=0pt\parskip=0pt\lineskip=0pt
\carttop
\hbox\bgroup
@@ -7801,6 +7806,8 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% Print arguments. Use slanted for @def*, typewriter for @deftype*.
\def\defunargs#1{%
\df \ifdoingtypefn \tt \else \sl \fi
+ \ifflagclear{txicodevaristt}{}%
+ {\def\var##1{{\setregularquotes \ttsl ##1}}}%
#1%
}
@@ -9311,6 +9318,12 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\imagexxx #1,,,,,\finish
\fi
}
+
+% Approximate height of a line in the standard text font.
+\newdimen\capheight
+\setbox0=\vbox{\tenrm H}
+\capheight=\ht0
+
%
% Arguments to @image:
% #1 is (mandatory) image filename; we tack on .eps extension.
@@ -9340,7 +9353,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
%
% Place image in a \vtop for a top page margin that is (close to) correct,
% as \topskip glue is relative to the first baseline.
- \vtop\bgroup\hrule height 0pt\vskip-\parskip
+ \vtop\bgroup \kern -\capheight \vskip-\parskip
\fi
%
% Enter horizontal mode so that indentation from an enclosing
@@ -11217,13 +11230,9 @@ directory should work if nowhere else does.}
%
\vsize = #1\relax
\advance\vsize by \topskip
- \outervsize = \vsize
- \advance\outervsize by 2\topandbottommargin
\txipageheight = \vsize
%
\hsize = #2\relax
- \outerhsize = \hsize
- \advance\outerhsize by 0.5in
\txipagewidth = \hsize
%
\normaloffset = #4\relax
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 0e55b6c1d2a..7de64829c0d 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -903,6 +903,30 @@ supports changing the remote login shell @command{/bin/sh}.
Check the @samp{Share SSH connections if possible} control for that
session.
+@item @option{docker}
+@cindex method @option{docker}
+@cindex @option{docker} method
+
+Integration for Docker containers. The host name may be either a
+running container's name or ID, as returned by @samp{docker ps}.
+
+@item @option{podman}
+@cindex method @option{podman}
+@cindex @option{podman} method
+
+Podman is an alternative to @option{docker} which may be run rootless,
+if desired.
+
+@item @option{kubernetes}
+@cindex method @option{kubernetes}
+@cindex @option{kubernetes} method
+
+Integration for containers in Kubernetes pods. The host name is a pod
+name returned by @samp{kubectl get pods}. The first container in a
+pod is used.
+
+This method does not support user names.
+
@end table
@@ -1763,36 +1787,21 @@ They can be installed with Emacs's Package Manager. This includes
@c @item ibuffer-tramp.el
@c Contact Svend Sorensen <svend@@ciffer.net>
-@item docker-tramp
-@cindex method @option{docker}
-@cindex @option{docker} method
-Integration for Docker containers. A container is accessed via
-@file{@trampfn{docker,user@@container,/path/to/file}}, where
-@samp{user} is the (optional) user that you want to use, and
-@samp{container} is the id or name of the container.
-
-@item kubernetes-tramp
-@cindex method @option{kubectl}
-@cindex @option{kubectl} method
-Integration for Docker containers deployed in a Kubernetes cluster.
-It is derived from @samp{docker-tramp}. A container is accessed via
-@file{@trampfn{kubectl,user@@container,/path/to/file}}, @samp{user}
-and @samp{container} have the same meaning as in @samp{docker-tramp}.
-
@item lxc-tramp
@cindex method @option{lxc}
@cindex @option{lxc} method
Integration for LXC containers. A container is accessed via
@file{@trampfn{lxc,container,/path/to/file}}, @samp{container} has the
-same meaning as in @samp{docker-tramp}. A @samp{user} specification
-is ignored.
+same meaning as with the @option{docker} method. A @samp{user}
+specification is ignored.
@item lxd-tramp
@cindex method @option{lxd}
@cindex @option{lxd} method
Integration for LXD containers. A container is accessed via
@file{@trampfn{lxd,user@@container,/path/to/file}}, @samp{user} and
-@samp{container} have the same meaning as in @samp{docker-tramp}.
+@samp{container} have the same meaning as with the @option{docker}
+method.
@item magit-tramp
@cindex method @option{git}
@@ -1997,10 +2006,10 @@ password of the target user. If these connections happen on the local
host, an entry with the local user and local host is used:
@example
-machine @var{HOST} port sudo login @var{USER} password secret
+machine @var{host} port sudo login @var{user} password secret
@end example
-@var{USER} and @var{HOST} are the strings returned by
+@var{user} and @var{host} are the strings returned by
@code{(user-login-name)} and @code{(system-name)}. If one of these
methods is connected via a multi hop (@pxref{Multi-hops}), the
credentials of the previous hop are used.
diff --git a/doc/misc/vhdl-mode.texi b/doc/misc/vhdl-mode.texi
index 7d451c71bd4..8abf882a291 100644
--- a/doc/misc/vhdl-mode.texi
+++ b/doc/misc/vhdl-mode.texi
@@ -892,7 +892,7 @@ list. Send email to the maintainer @email{reto@@gnu.org} to join
either of these lists.
The official Emacs VHDL Mode Home Page can be found at
-@uref{http://www.iis.ee.ethz.ch/~zimmi/emacs/vhdl-mode.html}.
+@uref{https://www.iis.ee.ethz.ch/~zimmi/emacs/vhdl-mode.html}.
@node Sample Init File
@chapter Sample Init File
diff --git a/etc/DEBUG b/etc/DEBUG
index f57e6f197bf..ef9160a2090 100644
--- a/etc/DEBUG
+++ b/etc/DEBUG
@@ -1004,7 +1004,7 @@ incompatible with the --with-dumping=unexec option of 'configure'.
** Running Emacs under Valgrind
-Valgrind <http://valgrind.org/> is free software that can be useful
+Valgrind <https://valgrind.org/> is free software that can be useful
when debugging low-level Emacs problems. Unlike GCC sanitizers,
Valgrind does not need you to compile Emacs with special debugging
flags, so it can be helpful in investigating problems that vanish when
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index 7f95cdd39a2..988eb1e09c8 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -59,9 +59,17 @@ which, when present, becomes the first argument passed to the "USER"
IRC command. The traditional way of setting this globally, via
'erc-email-userid', is still honored.
-** Additional display options for updated buffers.
-Additional flexibility is now available for controlling the behavior
-of newly created target buffers, especially during reconnection.
+** Changes to display options for new ERC buffers.
+The default value for the option 'erc-join-buffer', which determines
+how new buffers are displayed, has been changed to 'bury' for security
+reasons. Although the old value of 'buffer' is still accessible,
+along with its original behavior, users wanting a safer alternative
+can now opt for an improved 'window-noselect' instead. It still
+offers the same pronounced visual cue when connecting and joining but
+now avoids any hijacking of the active window as well.
+
+Beyond this, additional flexibility is now available for controlling
+the behavior of newly created target buffers during reconnection.
** Improved handling of multiline prompt input.
This means better detection and handling of intervening and trailing
@@ -77,6 +85,12 @@ now collapse into an alternate form designated by the option
but can be fine-tuned via the repurposed, formerly abandoned option
'erc-hide-prompt'.
+Certain commands provided by the 'erc-match' module, such as
+'erc-add-keyword', 'erc-add-pal', and others, now optionally ask
+whether to 'regexp-quote' the current input. A new option,
+'erc-match-quote-when-adding', has been added to allow for retaining
+the old behavior, if desired.
+
A bug has been fixed affecting users of the Soju bouncer: outgoing
messages during periods of heavy traffic no longer disappear.
diff --git a/etc/HELLO b/etc/HELLO
index d73465318ca..7bc12063f8e 100644
--- a/etc/HELLO
+++ b/etc/HELLO
@@ -24,6 +24,7 @@ Non-ASCII examples:
LANGUAGE (NATIVE NAME) HELLO
---------------------- -----
+Adlam (𞤀𞤣𞤤𞤢𞤥) 𞤅𞤢𞤤𞤢𞥄𞤥
Amharic (አማርኛ) ሠላም
Arabic (العربيّة) السّلام عليكم
Armenian (հայերեն) Բարև ձեզ
@@ -40,6 +41,7 @@ C printf (<x-color><param>orange red</param>"Hello, world!\n"</x-color>);
Cham (ꨌꩌ) ꨦꨤꩌ ꨦꨁꨰ
Cherokee (ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ) ᎣᏏᏲ / ᏏᏲ
Comanche /kəˈmæntʃiː/ Haa marʉ́awe
+Coptic (ⲘⲉⲧⲢⲉⲙ̀ⲛⲭⲏⲙⲓ) Ⲛⲟⲩϥⲣⲓ
Cree (ᓀᐦᐃᔭᐍᐏᐣ) ᑕᓂᓯ / ᐙᒋᔮ
Czech (čeština) Dobrý den
Danish (dansk) Hej / Goddag / Halløj
@@ -56,6 +58,7 @@ Finnish (suomi) Hei / Hyvää päivää
French (français) Bonjour / Salut
Georgian (ქართული) გამარჯობა
German (Deutsch) Guten Tag / Grüß Gott
+Gothic (𐌲𐌿𐍄𐌹𐍃𐌺𐌰) 𐌷𐌰𐌹𐌻𐍃 / 𐌷𐌰𐌹𐌻𐌰
Grantha (𑌗𑍍𑌰𑌨𑍍𑌥) 𑌨𑌮𑌸𑍍𑌤𑍇 / 𑌨𑌮𑌸𑍍𑌕𑌾𑌰𑌃
Greek (ελληνικά) Γειά σας
Greek, ancient (ἑλληνική) Οὖλέ τε καὶ μέγα χαῖρε
@@ -84,6 +87,7 @@ Maldivian (ދިވެހި) އައްސަލާމު ޢަލައިކުމް / ކިހިނ
Maltese (il-Malti) Bonġu / Saħħa
Mathematics ∀ p ∈ world • hello p □
Meetei Mayek (ꯃꯤꯇꯩ ꯃꯌꯦꯛ) ꯈꯨꯔꯨꯝꯖꯔꯤ
+Mende Kikakui (𞠀𞠁𞠂) 𞠛𞠉
Modi (𑘦𑘻𑘚𑘲) 𑘡𑘦𑘭𑘿𑘎𑘰𑘨
Mongolian (монгол хэл) Сайн байна уу?
Northern Thai (ᨣᩣᩴᨾᩮᩬᩥᨦ / ᨽᩣᩈᩣᩃ᩶ᩣ᩠ᨶᨶᩣ) ᩈ᩠ᩅᩢᩔ᩠ᨯᩦᨣᩕᩢ᩠ᨸ
@@ -111,9 +115,9 @@ Tibetan (བོད་སྐད་) བཀྲ་ཤིས་བདེ་ལེག
Tigrigna (ትግርኛ) ሰላማት
Tirhuta (𑒞𑒱𑒩𑒯𑒳𑒞𑒰) 𑒣𑓂𑒩𑒢𑒰𑒧 / 𑒮𑒲𑒞𑒰𑒩𑒰𑒧
Turkish (Türkçe) Merhaba
-Ukrainian (українська) Вітаю
+Ukrainian (українська) Вітаю / Добрий день! / Привіт
Vietnamese (tiếng Việt) Chào bạn
-
+Wancho (𞋒𞋀𞋉𞋃𞋕) 𞋂𞋈𞋛
<x-charset><param>japanese-jisx0208</param>Japanese (日本語) こんにちは</x-charset> <x-charset><param>katakana-jisx0201</param>/ コンニチハ
diff --git a/etc/HISTORY b/etc/HISTORY
index bb4e3e38e1b..9e4becc946e 100644
--- a/etc/HISTORY
+++ b/etc/HISTORY
@@ -226,6 +226,8 @@ GNU Emacs 27.2 (2021-03-25) emacs-27.2
GNU Emacs 28.1 (2022-04-04) emacs-28.1
+GNU Emacs 28.2 (2022-09-12) emacs-28.2
+
----------------------------------------------------------------------
This file is part of GNU Emacs.
diff --git a/etc/NEWS b/etc/NEWS
index 35d3db5ceb1..041fe0bdbd8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -24,6 +24,12 @@ applies, and please also update docstrings as needed.
* Installation Changes in Emacs 29.1
+---
+** Ahead-of-time native compilation can now be specified via configure.
+Use '--with-native-compilation=aot' to specify that all the Lisp files
+in the Emacs tree should be natively compiled ahead of time. (This is
+slow on most machines.)
+
+++
** Emacs can be built with built-in support for accessing SQLite databases.
This uses the popular sqlite3 library, and can be disabled by using
@@ -107,7 +113,7 @@ as was already the case for all the non-preloaded files.
** Emacs Sessions (Desktop)
+++
-*** New option to load a locked desktop if locking Emacs is not running.
+*** New user option to load a locked desktop if locking Emacs is not running.
The option 'desktop-load-locked-desktop' can now be set to the value
'check-pid', which means to allow loading a locked ".emacs.desktop"
file if the Emacs process which locked it is no longer running on the
@@ -164,9 +170,16 @@ time.
** Native Compilation
++++
+*** New variable 'inhibit-automatic-native-compilation'.
+If set, Emacs will inhibit native compilation (and won't write
+anything to the eln cache automatically). The variable is initialised
+from the 'EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION' environment
+variable on Emacs startup.
+
---
*** New command 'native-compile-prune-cache'.
-This command deletes older ".eln" cache entries (but not the ones for
+This command deletes older eln cache entries (but not the ones for
the current Emacs version).
---
@@ -174,14 +187,45 @@ the current Emacs version).
This function can be called in your init files to change the
user-specific directory where Emacs stores the "*.eln" files produced
by native compilation of Lisp packages Emacs loads. The default
-eln-cache directory is unchanged: it is the "eln-cache" subdirectory
+eln cache directory is unchanged: it is the "eln-cache" subdirectory
of 'user-emacs-directory'.
* Incompatible changes in Emacs 29.1
++++
+** The image commands have changed key bindings.
+In previous Emacs versions, images have had the '+', '-' and 'r' keys
+bound when point is over an image. In Emacs 29.1, additional commands
+were added, and this made it more likely that users would trigger the
+image commands by mistake. To avoid this, all image commands have
+moved to the 'i' keymap, so '+' is now 'i +', '-' is now 'i -', and
+'r' is now 'i r'. In addition, these commands are now repeating, so
+you can rotate an image twice by saying 'i r r', for instance.
+
++++
+** Emacs now picks the correct coding system for X input methods.
+Previously, Emacs would use the locale coding system for input
+methods, which could in some circumstances be incorrect, especially
+when the input method chose to fall back to some other coding system.
+
+Now, Emacs automatically detects the coding system used by input
+methods, and uses that to decode input in preference to the value of
+'locale-coding-system'. This unfortunately means that users who have
+changed the coding system used to decode X keyboard input must adjust
+their customizations to 'locale-coding-system' to the variable
+'x-input-coding-system' instead.
+
++++
+** Bookmarks no longer include context for encrypted files.
+If you're visiting an encrypted file, setting a bookmark no longer
+includes excerpts from that buffer in the bookmarks file. This is
+implemented by the new hook 'bookmark-inhibit-context-functions',
+where packages can register a function which returns non-nil for file
+names to be excluded from adding such excerpts.
+
---
-*** 'show-paren-mode' is now disabled in 'special-mode' buffers.
+** 'show-paren-mode' is now disabled in 'special-mode' buffers.
In Emacs versions previous to Emacs 28.1, 'show-paren-mode' defaulted
off. In Emacs 28.1, the mode was switched on in all buffers. In
Emacs 29.1, this was changed to be switched on in all editing-related
@@ -189,10 +233,10 @@ buffers, but not in buffers that inherit from 'special-mode'. To get
back to how things worked in Emacs 28.1, put the following in your
init file:
- (setopt show-paren-predicate t)
+ (setopt show-paren-predicate t)
+++
-*** Explicitly-set read-only state is preserved when reverting a buffer.
+** Explicitly-set read-only state is preserved when reverting a buffer.
If you use the 'C-x C-q' command to change the read-only state of the
buffer and then revert it, Emacs would previously use the file
permission bits to determine whether the buffer should be read-only
@@ -200,7 +244,7 @@ after reverting the buffer. Emacs now remembers the decision made in
'C-x C-q'.
---
-*** The Gtk selection face is no longer used for the region.
+** The Gtk selection face is no longer used for the region.
The combination of a Gtk-controlled background and a foreground color
controlled by the internal Emacs machinery led to low-contrast faces
in common default setups. Emacs now uses the same 'region' face on
@@ -373,6 +417,15 @@ startup. Previously, these functions ignored
'initial-scratch-message' and left "*scratch*" in 'fundamental-mode'.
---
+** Naming of Image-Dired thumbnail files has changed.
+Names of thumbnail files generated when 'image-dired-thumbnail-storage'
+is 'image-dired' now always end in ".jpg". This fixes various issues
+on different platforms, but means that thumbnails generated in Emacs 28
+will not be used in Emacs 29, and vice-versa. If disk space is an
+issue, consider deleting the 'image-dired-dir' directory after
+upgrading (usually "~/.emacs.d/image-dired/").
+
+---
** The 'rlogin' method in the URL library is now obsolete.
Emacs will now display a warning if you request a URL like
"rlogin://foo@example.org".
@@ -385,6 +438,35 @@ The user options 'url-gateway-rlogin-host',
are also obsolete.
---
+** The linum.el library is now obsolete.
+We recommend using either the built-in 'display-line-numbers-mode', or
+the 'nlinum' package from GNU ELPA instead. The former has better
+performance, but the latter is closer to a drop-in replacement.
+
+1. To use 'display-line-numbers-mode', add something like this to your
+ Init file:
+
+ (global-display-line-numbers-mode 1)
+ ;; Alternatively, to use it only in programming modes:
+ (add-hook 'prog-mode-hook #'display-line-numbers-mode)
+
+2. To use 'nlinum', add this to your Init file:
+
+ (package-install 'nlinum)
+ (global-nlinum-mode 1)
+ ;; Alternatively, to use it only in programming modes:
+ (add-hook 'prog-mode-hook #'nlinum-mode)
+
+3. To continue using the obsolete package 'linum', add this line to
+ your Init file, in addition to any existing customizations:
+
+ (require 'linum)
+
+---
+** The thumbs.el library is now obsolete.
+We recommend using 'M-x image-dired' instead.
+
+---
** The autoarg.el library is now marked obsolete.
This library provides the 'autoarg-mode' and 'autoarg-kp-mode' minor
modes to emulate the behavior of the historical editor Twenex Emacs.
@@ -424,6 +506,18 @@ option) and can be set to nil to disable Just-in-time Lock mode.
* Changes in Emacs 29.1
++++
+** New user option 'major-mode-remap-alist' to specify favorite major modes.
+This user option lets you remap the default modes (e.g. 'perl-mode' or
+'latex-mode') to your favorite ones (e.g. 'cperl-mode' or
+'LaTeX-mode') without having to use 'defalias', which can have
+undesirable side effects.
+This applies to all modes specified via 'auto-mode-alist', file-local
+variables, etc.
+
+---
+** Emacs now supports Unicode Standard version 15.0.
+
---
** New user option 'electric-quote-replace-consecutive'.
@@ -464,10 +558,6 @@ increase and decrease the font size globally. Additionally, the
user option 'global-text-scale-adjust-resizes-frames' controls whether
the frames are resized when the font size is changed.
-+++
-** New function 'file-parent-directory'.
-Get the parent directory of a file.
-
** New config variable 'syntax-wholeline-max' to reduce the cost of long lines.
This variable is used by some operations (mostly syntax-propertization
and font-locking) to treat lines longer than this variable as if they
@@ -578,8 +668,9 @@ If non-nil, this option allows scrolling a window while dragging text
around without a scroll wheel.
+++
-*** 'mouse-drag-copy-region' can now be 'non-empty'.
-This inhibits putting empty strings onto the kill ring.
+*** The value of 'mouse-drag-copy-region' can now be the symbol 'non-empty'.
+This prevents mouse drag gestures from putting empty strings onto the
+kill ring.
+++
** New user options 'dnd-indicate-insertion-point' and 'dnd-scroll-margin'.
@@ -612,7 +703,9 @@ yes/no question before executing. The new function 'command-query' is
a convenient method of making commands disabled in this way.
---
-** 'count-lines' will now report buffer totals if given a prefix.
+** 'count-words' will now report buffer totals if given a prefix.
+Without a prefix, it will only report the word count for the narrowed
+part of the buffer.
+++
** 'count-words' will now report sentence count when used interactively.
@@ -658,11 +751,6 @@ This value stands for the value of the corresponding attribute of the
inheriting from other faces.
+++
-** New function 'buffer-text-pixel-size'.
-This is similar to 'window-text-pixel-size', but can be used when the
-buffer isn't displayed.
-
-+++
** New X resource: "borderThickness".
This controls the thickness of the external borders of the menu bars
and pop-up menus.
@@ -774,6 +862,16 @@ doesn't support. It is most useful with the Linux console and similar
terminals, where Emacs has a reliable way of determining which
characters have glyphs in the font loaded into the terminal's memory.
+---
+*** New functions to set terminal output buffer size.
+The new functions 'tty--set-output-buffer-size' and
+'tty--output-buffer-size' allow setting and retrieving the output
+buffer size of a terminal device. The default buffer size is and has
+always been BUFSIZ, which is defined in your system's stdio.h. When
+you set a buffer size with 'tty--set-output-buffer-size', this also
+prevents Emacs from explicitly flushing the tty output stream, except
+at the end of display update.
+
** ERT
+++
@@ -926,6 +1024,12 @@ The apropos commands will now select the apropos window if
If the symbol at point is a keymap, 'describe-keymap' suggests it as
the default candidate.
+---
+*** New command 'help-quick' displays an overview of common commands.
+The command pops up a buffer at the bottom of the screen with a few
+helpful commands for various tasks. You can toggle the display using
+'C-h q'.
+
** Outline Mode
+++
@@ -944,7 +1048,14 @@ or is itself too long.
*** New user option 'outline-minor-mode-use-buttons'.
If non-nil, Outline Minor Mode will use buttons to hide/show outlines
in addition to the ellipsis. The default is nil in editing modes, but
-non-nil in 'special-mode' and its derivatives.
+non-nil in 'help-mode' and its derivatives.
+
++++
+*** New user option 'outline-minor-mode-use-margins'.
+If non-nil, Outline Minor Mode will use the window margins to
+hide/show outlines in addition to the ellipsis. The default is
+non-nil in 'special-mode' and its derivatives, and it can be used in
+editing modes.
** Windows
@@ -1035,6 +1146,30 @@ Rcirc will use the default 'completion-at-point' mechanism. The
conventional IRC behavior of completing by cycling through the
available options can be restored by enabling this option.
++++
+*** New user option 'rcirc-bridge-bot-alist'.
+If you are in a channel where a bot is responsible for bridging
+between networks, you can use this variable to make these messages
+appear more native. For example you might set the option to:
+
+ (setq rcirc-bridge-bot-alist '(("bridge" . "{\\(.+?\\)}[[:space:]]+")))
+
+for messages like
+
+ 09:47 <bridge> {john} I am not on IRC
+
+to be reformatted into
+
+ 09:47 <john> I am not on IRC
+
+---
+*** New formatting commands.
+Most IRC clients (including rcirc) support basic formatting using
+control codes. Under the 'C-c C-f' prefix a few commands have been
+added to insert these automatically. For example, if a region is
+active and 'C-c C-f C-b' is invoked, markup is inserted for the region
+to be highlighted bold.
+
** Imenu
+++
@@ -1142,6 +1277,14 @@ When nil, this prevents comint from deleting the current input when
inserting previous input using '<mouse-2>'. The default is t, to
preserve past behavior.
+---
+*** New minor mode 'comint-fontify-input-mode'.
+This minor mode is enabled by default in "*shell*" and "*ielm*"
+buffers. It fontifies input text according to 'shell-mode' or
+'emacs-lisp-mode' font-lock rules. Customize the user options
+'shell-fontify-input-enable' and 'ielm-fontify-input-enable' to nil if
+you don't want to enable input fontification by default.
+
** Mwheel
---
@@ -1166,10 +1309,10 @@ to edit such sequences by allowing point to "enter" the sequence.
*** Support for many old scripts and writing systems.
Emacs now supports and has language-environments and input methods for
several dozens of old scripts that were used in the past for various
-languages in South and South-East Asia. For each such script Emacs
-now has font-selection and character composition rules, a language
-environment, and an input method. The newly-added scripts and the
-corresponding language environments are:
+languages. For each such script Emacs now has font-selection and
+character composition rules, a language environment, and an input
+method. The newly-added scripts and the corresponding language
+environments are:
Tai Tham script and the Northern Thai language environment
Brahmi script and language environment
@@ -1196,6 +1339,12 @@ Grantha script and language environment
Kharoshthi script and language environment
Lepcha script and language environment
Meetei Mayek script and language environment
+Adlam script and language environment
+Mende Kikakui script and language environment
+Wancho script and language environment
+Toto script and language environment
+Gothic script and language environment
+Coptic script and language environment
---
*** The "Oriya" language environment was renamed to "Odia".
@@ -1210,6 +1359,9 @@ Type 'C-u C-h t' to select it in case your language setup does not do
so automatically.
---
+*** New Ukrainian translation of the Emacs Tutorial.
+
+---
*** New default phonetic input method for the Tamil language environment.
The default input method for the Tamil language environment is now
"tamil-phonetic" which is a customizable phonetic input method. To
@@ -1222,9 +1374,19 @@ change the input method's translation rules, customize the user option
** ecomplete
---
+*** New commands 'ecomplete-edit' and 'ecomplete-remove'.
+These allow you to (respectively) edit and bulk-remove entries from
+the ecomplete database.
+
+---
*** New user option 'ecomplete-auto-select'.
If non-nil and there's only one matching option, auto-select that.
+---
+*** New user option 'ecomplete-filter-regexp'.
+If non-nil, this user option describes what entries not to add to the
+database stored on disk.
+
** Dired
+++
@@ -1317,6 +1479,10 @@ This controls how statements like the following are indented:
foo &&
bar
+*** New Flymake backend using the ShellCheck program.
+It is enabled by default, but requires that the external "shellcheck"
+command is installed.
+
** Cperl Mode
---
@@ -1471,8 +1637,8 @@ characters instead of just 'SPC' and 'TAB'.
This mode adds some highlighting, fixes the 'M-q' command, and has
commands for doing maintenance of the Emacs NEWS files. In addition,
this mode turns on 'outline-minor-mode', and thus displays
-customizable icons (see 'icon-preference') on heading lines. To
-disable these icons, customize 'outline-minor-mode-use-buttons' to a
+customizable icons (see 'icon-preference') in the margins. To
+disable these icons, customize 'outline-minor-mode-use-margins' to a
nil value.
---
@@ -1482,7 +1648,7 @@ uses the 'key-parse' syntax. It replaces the old 'kmacro-lambda-form'
(which is now declared obsolete).
---
-** 'savehist.el' can now truncate variables that are too long.
+** savehist.el can now truncate variables that are too long.
An element of 'savehist-additional-variables' can now be of the form
'(VARIABLE . MAX-ELTS)', which means to truncate the VARIABLE's value to
at most MAX-ELTS elements (if the value is a list) before saving the
@@ -1588,7 +1754,7 @@ Non-nil means that the default definitions of equivalent characters
are overridden.
*** New command 'describe-char-fold-equivalences'.
-It displays character equivalences used by `char-fold-to-regexp'.
+It displays character equivalences used by 'char-fold-to-regexp'.
+++
*** New command 'isearch-emoji-by-name'.
@@ -1645,8 +1811,23 @@ This fills the region to be no wider than a specified pixel width.
This will take you to the gnu.org web server's version of the current
info node. This command only works for the Emacs and Emacs Lisp manuals.
+** Shortdoc
+
+---
+*** New command 'shortdoc-copy-function-as-kill' bound to 'w'.
+It copies the name of the function near point into the kill ring.
+
+---
+*** 'N' and 'P' are now bound to 'shortdoc-{next,previous}-section'.
+This is in addition to the old keybindings 'C-c C-n' and 'C-c C-p'.
+
** VC
+---
+*** New command 'vc-pull-and-push'.
+This commands first does a "pull" command, and if that is successful,
+do a "push" command afterwards.
+
+++
*** 'C-x v b' prefix key is used now for branch commands.
'vc-print-branch-log' is bound to 'C-x v b l', and new commands are
@@ -1659,6 +1840,13 @@ commands.
This command marks files based on a regexp. If given a prefix
argument, unmark instead.
++++
+*** New command 'C-x v !' ('vc-edit-next-command').
+This prefix command requests editing of the next VC shell command
+before execution. For example, in a Git repository, you can produce a
+log of more than one branch by typing 'C-x v ! C-x v b l' and then
+appending additional branch names to the 'git log' command.
+
---
*** 'C-x v v' in a diffs buffer allows to commit only some of the changes.
This command is intended to allow you to commit only some of the
@@ -1681,9 +1869,32 @@ consistent with 'vc-responsible-backend'.
---
*** Log Edit now font locks long Git commit summary lines.
Writing shorter summary lines avoids truncation in contexts in which
-Git commands display summary lines. See the two new variables
+Git commands display summary lines. See the two new user options
'vc-git-log-edit-summary-target-len' and 'vc-git-log-edit-summary-max-len'.
+---
+*** New 'log-edit-headers-separator' face.
+It is used to style the line that separates the 'log-edit' headers
+from the 'log-edit' summary.
+
+---
+*** The function 'vc-read-revision' accepts a new MULTIPLE argument.
+If non-nil, multiple revisions can be queried. This is done using
+'completing-read-multiple'.
+
+---
+*** New function 'vc-read-multiple-revisions'.
+This function invokes 'vc-read-revision' with a non-nil value for
+MULTIPLE.
+
++++
+*** New command 'vc-prepare-patch'.
+Patches for any version control system can be prepared using VC. The
+command will query what commits to send and will compose messages for
+your mail user agent. The behavior of 'vc-prepare-patch' can be
+modified by the user options 'vc-prepare-patches-separately' and
+'vc-default-patch-addressee'.
+
** Message
---
@@ -1951,11 +2162,16 @@ as opposed to via the command-line.
*** New command 'image-transform-fit-to-window'.
This command fits the image to the current window by scaling down or
up as necessary. Unlike 'image-transform-fit-both', this does not
-only scale the image down, but up as well. It is bound to "s w" in
+only scale the image down, but up as well. It is bound to 's w' in
Image Mode by default.
+---
+*** New command 'image-mode-wallpaper-set'.
+This command sets the desktop background to the current image. It is
+bound to 'W' by default.
+
+++
-*** 'image-transform-fit-to-(height|width)' are now obsolete.
+*** 'image-transform-fit-to-{height,width}' are now obsolete.
Use the new command 'image-transform-fit-to-window' instead.
The keybinding for 'image-transform-fit-to-width' is now 's i'.
@@ -1976,12 +2192,21 @@ this message for SVG and XPM.
+++
*** New commands: 'image-flip-horizontally' and 'image-flip-vertically'.
-These commands horizontally and vertically flip the image under point.
+These commands horizontally and vertically flip the image under point,
+and are bound to 'i h' and 'i v', respectively.
+++
*** New command 'image-transform-set-percent'.
It allows setting the image size to a percentage of its original size,
-and is bound to "s p" in Image mode.
+and is bound to 's p' in Image mode.
+
++++
+*** 'image-transform-original' renamed to 'image-transform-reset-to-original'.
+The old name was confusing, and is now an obsolete function alias.
+
++++
+*** 'image-transform-reset' renamed to 'image-transform-reset-to-initial'.
+The old name was confusing, and is now an obsolete function alias.
** Images
@@ -1992,53 +2217,54 @@ This is done via 'image-converter-add-handler'.
** Image-Dired
+++
-*** 'image-dired-display-image-mode' is now based on 'image-mode'.
+*** 'image-dired-image-mode' is now based on 'image-mode'.
This avoids converting images in the background, and makes Image-Dired
noticeably faster. New keybindings from 'image-mode' are now
available in the "*image-dired-display-image*" buffer; press '?' or
-'h' in that buffer to see the full list. Finally, some commands and
-user options that are no longer needed are now obsolete:
-'image-dired-cmd-create-temp-image-options',
-'image-dired-cmd-create-temp-image-program',
-'image-dired-display-current-image-full',
-'image-dired-display-current-image-sized',
-'image-dired-display-window-height-correction',
-'image-dired-display-window-width-correction',
-'image-dired-temp-image-file'.
+'h' in that buffer to see the full list.
---
*** Navigation and marking commands now work in image display buffer.
The following new bindings have been added:
+- 'n', 'SPC' => 'image-dired-display-next'
+- 'p', 'DEL' => 'image-dired-display-previous'
+- 'm' => 'image-dired-mark-thumb-original-file'
+- 'd' => 'image-dired-flag-thumb-original-file'
+- 'u' => 'image-dired-unmark-thumb-original-file'
- n or SPC image-dired-display-next-thumbnail-original
- p or DEL image-dired-display-previous-thumbnail-original
- m image-dired-mark-thumb-original-file
- d image-dired-flag-thumb-original-file
- u image-dired-unmark-thumb-original-file
+---
+*** New command 'image-dired-unmark-all-marks'.
+It removes all marks from all files in the thumbnail and the
+associated Dired buffer, and is bound to 'U' in the thumbnail and
+display buffer.
---
-*** Reduce dependency on external "exiftool" command.
-The 'image-dired-copy-with-exif-file-name' no longer requires an
-external "exiftool" command to be available. The user options
-'image-dired-cmd-read-exif-data-program' and
-'image-dired-cmd-read-exif-data-options' are now obsolete.
+*** New command 'image-dired-do-flagged-delete'.
+It deletes all flagged files, and is bound to 'x' in the thumbnail
+buffer. It replaces the command 'image-dired-delete-marked', which is
+now an obsolete alias.
---
-*** New command for the thumbnail buffer.
-The new command 'image-dired-unmark-all-marks' has been added. It is
-bound to 'U' in the thumbnail and display buffer.
+*** New command 'image-dired-copy-filename-as-kill'.
+It copies the name of the marked or current image to the kill ring,
+and is bound to 'w' in the thumbnail buffer.
---
-*** Support Thumbnail Managing Standard v0.9.0 (Dec 2020).
-This standard allows sharing generated thumbnails across different
-programs. Version 0.9.0 adds two larger thumbnail sizes: 512x512 and
-1024x1024 pixels. See the user option 'image-dired-thumbnail-storage'
-to use it; it is not enabled by default.
+*** New command 'image-dired-wallpaper-set'.
+This command sets the desktop background to the image at point in the
+thumbnail buffer. It is bound to 'W' by default.
---
-*** Support GraphicsMagick command line tools.
-Support for the GraphicsMagick command line tool ("gm") has been
-added, and is used instead of ImageMagick when it is available.
+*** 'image-dired-slideshow-start' is now bound to 'S'.
+It is bound in both the thumbnail and display buffer, and no longer
+prompts for a timeout; use a numerical prefix (e.g. 'C-u 8 S') to set
+the timeout.
+
+---
+*** New user option 'image-dired-marking-shows-next'.
+If this option is non-nil (the default), marking, unmarking or
+flagging an image in either the thumbnail or display buffer shows the
+next image.
---
*** New face 'image-dired-thumb-flagged'.
@@ -2047,16 +2273,53 @@ used for images that are flagged for deletion in the Dired buffer
associated with Image-Dired.
---
-*** 'image-dired-slideshow-start' is now bound to 'S'.
-It is bound in both the thumbnail and display buffer.
+*** Image information is now shown in the header line of the thumbnail buffer.
+This replaces the message that most navigation commands in the
+thumbnail buffer used to show at the bottom of the screen.
---
-*** The 'image-dired-slideshow-start' command no longer prompts.
-It no longer inconveniently prompts for a number of images and a
-delay: it runs indefinitely, but stops automatically on any command.
-You can set the delay with a prefix argument, or a negative prefix
-argument to prompt for a delay. Customize the user option
-'image-dired-slideshow-delay' to change the default from 5 seconds.
+*** New specifiers for 'image-dired-display-properties-format'.
+This is used to format the new header line. The new specifiers are:
+"%d" for the name of the directory that the file is in, "%n" for
+file's number in the thumbnail buffer, and "%s" for the file size.
+
+The default format has been updated to use this. If you prefer the
+old format, add this to your Init file:
+
+ (setopt image-dired-display-properties-format "%b: %f (%t): %c")
+
+---
+*** New faces for the header line of the thumbnail buffer.
+These faces correspond to different parts of the header line, as
+specified in 'image-dired-display-properties-format':
+- 'image-dired-thumb-header-directory-name'
+- 'image-dired-thumb-header-file-name'
+- 'image-dired-thumb-header-file-size'
+- 'image-dired-thumb-header-image-count'
+
+---
+*** PDF support.
+Image-Dired now displays thumbnails for PDF files. Type 'RET' on a
+PDF file in the thumbnail buffer to visit the corresponding PDF.
+
+---
+*** Support GraphicsMagick command line tools.
+Support for the GraphicsMagick command line tool ("gm") has been
+added, and is used instead of ImageMagick when it is available.
+
+---
+*** Support Thumbnail Managing Standard v0.9.0 (Dec 2020).
+This standard allows sharing generated thumbnails across different
+programs. Version 0.9.0 adds two larger thumbnail sizes: 512x512 and
+1024x1024 pixels. See the user option 'image-dired-thumbnail-storage'
+to use it; it is not enabled by default.
+
+---
+*** Reduce dependency on external "exiftool" command.
+The 'image-dired-copy-with-exif-file-name' no longer requires an
+external "exiftool" command to be available. The user options
+'image-dired-cmd-read-exif-data-program' and
+'image-dired-cmd-read-exif-data-options' are now obsolete.
---
*** Support for bookmark.el.
@@ -2065,15 +2328,12 @@ the thumbnail view, and will create a bookmark that opens the current
directory in Image-Dired.
---
-*** New user option 'image-dired-marking-shows-next'.
-If this option is non-nil (the default), marking, unmarking or
-flagging an image in either the thumbnail or display buffer shows the
-next image.
-
----
-*** Image information is now shown in the header line.
-This replaces the message most navigation commands in the thumbnail
-buffer used to show at the bottom of the screen.
+*** The 'image-dired-slideshow-start' command no longer prompts.
+It no longer inconveniently prompts for a number of images and a
+delay: it runs indefinitely, but stops automatically on any command.
+You can set the delay with a prefix argument, or a negative prefix
+argument to prompt for a delay. Customize the user option
+'image-dired-slideshow-delay' to change the default from 5 seconds.
+++
*** 'image-dired-show-all-from-dir-max-files' increased to 1000.
@@ -2084,10 +2344,29 @@ important as it used to be. You can now also customize this option to
nil to disable this confirmation completely.
---
-*** 'image-dired-rotate-thumbnail-(left|right)' is now obsolete.
-Instead, use commands 'image-dired-refresh-thumb' to generate a new
-thumbnail, or 'image-rotate' to rotate the thumbnail without updating
-the thumbnail file.
+*** 'image-dired-thumb-size' increased to 128.
+
++++
+*** 'image-dired-db-file' renamed to 'image-dired-tags-db-file'.
+
+---
+*** 'image-dired-display-image-mode' renamed to 'image-dired-image-mode'.
+The corresponding keymap is now named 'image-dired-image-mode-map'.
+
++++
+*** Some commands have been renamed to be shorter.
+- 'image-dired-display-thumbnail-original-image' has been renamed to
+ 'image-dired-display-this'.
+- 'image-dired-display-next-thumbnail-original' has been renamed to
+ 'image-dired-display-next'.
+- 'image-dired-display-previous-thumbnail-original' has been renamed
+ to 'image-dired-display-previous'.
+The old names are now obsolete aliases.
+
+---
+*** 'image-dired-thumb-{height,width}' are now obsolete.
+Customize 'image-dired-thumb-size' instead, which will set both the
+height and width.
---
*** HTML image gallery generation is now obsolete.
@@ -2096,6 +2375,24 @@ now obsolete: 'image-dired-gallery-thumb-image-root-url',
'image-dired-gallery-hidden-tags', 'image-dired-gallery-dir',
'image-dired-gallery-image-root-url'.
+---
+*** 'image-dired-rotate-thumbnail-{left,right}' are now obsolete.
+Instead, use commands 'image-dired-refresh-thumb' to generate a new
+thumbnail, or 'image-rotate' to rotate the thumbnail without updating
+the thumbnail file.
+
++++
+*** Some commands and user options are now obsolete.
+Since 'image-dired-display-image-mode' is now based on 'image-mode',
+some commands and user options are no longer needed and are now obsolete:
+'image-dired-cmd-create-temp-image-options',
+'image-dired-cmd-create-temp-image-program',
+'image-dired-display-current-image-full',
+'image-dired-display-current-image-sized',
+'image-dired-display-window-height-correction',
+'image-dired-display-window-width-correction',
+'image-dired-temp-image-file'.
+
** Dired
---
@@ -2149,9 +2446,9 @@ recently set.
It is bound to the new command 'bookmark-edit-annotation-cancel'.
---
-*** New option 'bookmark-fringe-mark'.
+*** New user option 'bookmark-fringe-mark'.
This option controls the bitmap used to indicate bookmarks in the
-fringe (or 'nil' to disable showing this marker).
+fringe (or nil to disable showing this marker).
** Exif
@@ -2201,6 +2498,11 @@ and friends.
** Tramp
++++
+*** New connection methods "docker", "podman" and "kubernetes".
+They allow accessing environments provided by Docker and similar
+programs.
+
---
*** Tramp supports abbreviating remote home directories now.
When calling 'abbreviate-file-name' on a Tramp file name, the result
@@ -2253,7 +2555,7 @@ in the project root directory and is shared among all project buffers.
Without a prefix argument, the kind of shell (buffer-dedicated,
project-dedicated or global) is specified by the new
-'python-shell-dedicated' variable.
+'python-shell-dedicated' user option.
** Ruby Mode
@@ -2279,14 +2581,15 @@ automatically insert the Tramp prefix. The automatic insertion
applies only when 'default-directory' is remote and the command is a
Lisp function. This frees you from having to keep track of whether
commands are Lisp function or external when supplying absolute file
-name arguments. See "Electric forward slash" in the Eshell manual.
+name arguments. See the "(eshell) Electric forward slash" node in the
+Eshell manual for details.
+++
*** Improved support for redirection operators in Eshell.
Eshell now supports a wider variety of redirection operators. For
example, you can now redirect both stdout and stderr via '&>' or
duplicate one output handle to another via 'NEW-FD>&OLD-FD'. For more
-information, see "Redirections" in the Eshell manual.
+information, see the "(eshell) Redirection" node in the Eshell manual.
+++
*** Double-quoting an Eshell expansion now treats the result as a single string.
@@ -2336,6 +2639,12 @@ behavior, customize the new 'eshell-lisp-form-nil-is-failure' option.
Enabling this will automatically kill a "*shell*" buffer as soon as
the shell session terminates.
+---
+*** New minor mode 'shell-highlight-undef-mode'.
+Customize 'shell-highlight-undef-enable' to t if you want to enable
+this minor mode in "*shell*" buffers. It will highlight undefined
+commands with a warning face as you type.
+
** Calc
+++
@@ -2379,6 +2688,19 @@ Enabling this minor mode turns on hiding header material, like
'elide-head' does; disabling it shows the header. The commands
'elide-head' and 'elide-head-show' are now obsolete.
+*** New package ansi-osc.el.
+Support for OSC ("Operating System Command") escape sequences has been
+extracted from comint.el in order to provide interpretation of OSC
+sequences in compilation buffers.
+
+Adding the new function 'ansi-osc-compilation-filter' to
+'compilation-filter-hook' enables interpretation of OSC escape
+sequences in compilation buffers. By default, all sequences are
+filtered out.
+
+The list of handlers (already covering OSC 7 and 8) has been extended
+with a handler for OSC 2, the command to set a window title.
+
+++
*** New user option 'project-vc-include-untracked'.
If non-nil, files untracked by a VCS are considered to be part of
@@ -2405,7 +2727,7 @@ instead of also trying to ping it. Customize the user option
*** The 'run-dig' command is now obsolete; use 'dig' instead.
---
-*** Some `bib-mode' commands and variables have been renamed.
+*** Some 'bib-mode' commands and variables have been renamed.
To respect Emacs naming conventions, the variable 'unread-bib-file'
has been renamed to 'bib-unread-file'. The following commands have
also been renamed:
@@ -2426,10 +2748,37 @@ remote host are shown. Alternatively, the user option
*** 'outlineify-sticky' command is renamed to 'allout-outlinify-sticky'.
The old name is still available as an obsolete function alias.
+---
+*** New command 'world-clock-copy-time-as-kill' for 'M-x world-clock'.
+It copies the current line into the kill ring.
+
+---
+*** 'edit-abbrevs' now uses font-locking.
+The new face 'abbrev-table-name' is used to display the abbrev table
+name.
+
* New Modes and Packages in Emacs 29.1
+++
+** New commands 'image-crop' and 'image-cut.
+These commands allow interactively cropping/cutting the image at
+point. The commands are bound to keys 'i c' and 'i x' (respectively)
+in the local keymap over images. They rely on external programs, by
+default "convert" from ImageMagick, to do the actual cropping/eliding
+of the image file.
+
+---
+** New package 'wallpaper'.
+This package provides the command 'wallpaper-set', which sets the
+desktop background image. Depending on the system and the desktop,
+this may require an external program (such as "swaybg", "gm",
+"display" or "xloadimage"). If so, a suitable command should be
+detected automatically in most cases. It can also be customized
+manually if needed, using the new user options 'wallpaper-command' and
+'wallpaper-command-args'.
+
++++
** New package 'oclosure'.
Allows the creation of "functions with slots" or "function objects"
via the macros 'oclosure-define' and 'oclosure-lambda'.
@@ -2485,18 +2834,23 @@ in-memory format is now by using ':data-width' and ':data-height'.
** "loaddefs.el" generation has been reimplemented.
The various "loaddefs.el" files in the Emacs tree (which contain
information about autoloads, built-in packages and package prefixes)
-used to be generated by functions in "autoloads.el". These are now
-generated by "loaddefs-gen.el" instead. This leads to functionally
-equivalent loaddef files, but they do not use exactly the same syntax,
-so using 'M-x update-file-autoloads' no longer works. (This didn't
-work well in most files in the past, either, but it will now signal an
-error in any file.)
+used to be generated by functions in autoloads.el. These are now
+generated by loaddefs-gen.el instead. This leads to functionally
+equivalent "loaddef.el" files, but they do not use exactly the same
+syntax, so using 'M-x update-file-autoloads' no longer works. (This
+didn't work well in most files in the past, either, but it will now
+signal an error in any file.)
In addition, files are scanned in a slightly different way.
-Previously ';;;###' specs inside a top-level form (i.e., something
+Previously, ';;;###' specs inside a top-level form (i.e., something
like '(when ... ;;;### ...)' would be ignored. They are now parsed as
normal.
+---
+** Themes have special autoload cookies.
+All build-in themes are scraped for ;;;###theme-autoload cookies that
+are loaded along with the regular auto-loaded code.
+
+++
** 'buffer-modified-p' has been extended.
This function was previously documented to return only nil or t. This
@@ -2635,7 +2989,7 @@ It's been obsolete since Emacs-22.1, actually.
negative arguments, and is generally slower than 'ash', which should be
used instead. This warning can be suppressed by surrounding calls to
'lsh' with the construct '(with-suppressed-warnings ((suspicious lsh)) ...)',
-but switching to `ash` is generally much preferable.
+but switching to 'ash' is generally much preferable.
---
** Some functions and variables obsolete since Emacs 24 have been removed:
@@ -2698,7 +3052,7 @@ but switching to `ash` is generally much preferable.
'pascal-last-completions', 'pascal-show-completions',
'pascal-toggle-completions', 'pcomplete-arg-quote-list',
'pcomplete-quote-argument', 'prolog-char-quote-workaround',
-'python-buffer, 'python-guess-indent', 'python-indent',
+'python-buffer', 'python-guess-indent', 'python-indent',
'python-info-ppss-comment-or-string-p', 'python-info-ppss-context',
'python-info-ppss-context-type', 'python-preoutput-result',
'python-proc', 'python-send-receive', 'python-send-string',
@@ -2772,7 +3126,7 @@ functions.
---
** '?\' at the end of a line now signals an error.
-Previously it produced a nonsense value, -1, that was never intended.
+Previously, it produced a nonsense value, -1, that was never intended.
---
** Some libraries obsolete since Emacs 24.1 and 24.3 have been removed:
@@ -2785,19 +3139,19 @@ patcomp.el, pc-mode.el, pc-select.el, s-region.el, and sregex.el.
Emacs has a number of rather obscure generalized variables defined,
that, for instance, allowed you to say things like:
- (setf (point-min) 4)
+ (setf (point-min) 4)
These never caught on and have been made obsolete. The form above,
for instance, is the same as saying
- (narrow-to-region 4 (point-max))
+ (narrow-to-region 4 (point-max))
The following generalized variables have been made obsolete:
'buffer-file-name', 'buffer-local-value', 'buffer-modified-p',
'buffer-name', 'buffer-string', 'buffer-substring', 'current-buffer',
'current-column', 'current-global-map', 'current-input-mode',
'current-local-map', 'current-window-configuration',
-'default-file-modes', 'documentation-property', 'frame-height',
+'default-file-modes', 'documentation-property', 'eq', 'frame-height',
'frame-width', 'frame-visible-p', 'global-key-binding',
'local-key-binding', 'mark', 'mark-marker', 'marker-position',
'mouse-position', 'point', 'point-marker', 'point-max', 'point-min',
@@ -2810,6 +3164,17 @@ The following generalized variables have been made obsolete:
* Lisp Changes in Emacs 29.1
+++
+** New accessor function 'file-attribute-file-identifier'.
+It returns the list of the inode number and device identifier
+retrieved by 'file-attributes'. This value can be used to identify a
+file uniquely. The device identifier can be a single number or (for
+remote files) a cons of 2 numbers.
+
++++
+** New macro 'while-let'.
+This is like 'when-let', but repeats until a binding form is nil.
+
++++
** New function 'make-obsolete-generalized-variable'.
This can be used to mark setters used by 'setf' as obsolete, and the
byte-compiler will then warn about using them.
@@ -2847,11 +3212,6 @@ These can be used for buttons in buffers and the like. See the
"(elisp) Icons" and "(emacs) Icons" nodes in the manuals for details.
+++
-** New function 'seq-positions'.
-This returns a list of the (zero-based) indices of elements matching a
-given predicate in the specified sequence.
-
-+++
** New arguments MESSAGE and TIMEOUT of 'set-transient-map'.
MESSAGE specifies a message to display after activating the transient
map, including a special formatting spec to list available keys.
@@ -2860,15 +3220,6 @@ The default timeout value can be defined by the new variable
'set-transient-map-timeout'.
+++
-** New function 'seq-split'.
-This returns a list of sub-sequences of the specified sequence.
-
-+++
-** New function 'seq-remove-at-position'.
-This function returns a copy of the specified sequence where the
-element at a given (zero-based) index got removed.
-
-+++
** 'plist-get', 'plist-put' and 'plist-member' are no longer limited to 'eq'.
These function now take an optional comparison predicate argument.
@@ -2929,6 +3280,27 @@ When called with a new optional argument UNICODE non-nil, 'max-char'
will now report the maximum valid codepoint defined by the Unicode
Standard.
+** seq
+
++++
+** New function 'seq-split'.
+This returns a list of sub-sequences of the specified sequence.
+
++++
+** New function 'seq-remove-at-position'.
+This function returns a copy of the specified sequence where the
+element at a given (zero-based) index got removed.
+
++++
+** New function 'seq-positions'.
+This returns a list of the (zero-based) indices of elements matching a
+given predicate in the specified sequence.
+
++++
+** New function 'seq-keep'.
+This is like 'seq-map', but removes all nil results from the returned
+list.
+
** Themes
---
@@ -3324,6 +3696,10 @@ a valid key sequence according to 'key-valid-p'.
This returns a list of all the components of a file name.
+++
+** New function 'file-name-parent-directory'.
+This returns the parent directory of a file name.
+
++++
** New macro 'with-undo-amalgamate'.
It records a particular sequence of operations as a single undo step.
@@ -3432,11 +3808,27 @@ This means the vscroll will not be reset when set on a window that is
** XDG support
---
-*** New function 'xdg-state-home' returns 'XDG_STATE_HOME' environment variable.
-This new location, introduced in the XDG Base Directory Specification
-version 0.8 (8th May 2021), "contains state data that should persist
+*** New function 'xdg-state-home'.
+It returns the new 'XDG_STATE_HOME' environment variable. It should
+point to a file name that "contains state data that should persist
between (application) restarts, but that is not important or portable
enough to the user that it should be stored in $XDG_DATA_HOME".
+(This variable was introduced in the XDG Base Directory Specification
+version 0.8 released on May 8, 2021.)
+
+---
+*** New function 'xdg-current-desktop'.
+It returns a list of strings, corresponding to the colon-separated
+list of names in the 'XDG_CURRENT_DESKTOP' environment variable, which
+identify the current desktop environment.
+(This variable was introduced in XDG Desktop Entry Specification
+version 1.2.)
+
+---
+*** New function 'xdg-session-type'.
+It returns the 'XDG_SESSION_TYPE' environment variable. (This is not
+part of any official standard; see the man page pam_systemd(8) for
+more information.)
+++
** New macro 'with-delayed-message'.
@@ -3510,6 +3902,11 @@ This function returns t if point is on a valid image, and nil
otherwise.
+++
+** New function 'buffer-text-pixel-size'.
+This is similar to 'window-text-pixel-size', but can be used when the
+buffer isn't displayed.
+
++++
** New function 'string-pixel-width'.
This returns the width of a string in pixels. This can be useful when
dealing with variable pitch fonts and glyphs that have widths that
@@ -3700,6 +4097,18 @@ the same but works by modifying LIST destructively.
---
** 'string-split' is now an alias for 'split-string'.
++++
+** 'format-spec' now accepts functions in the replacement.
+The function is called only when used in the format string. This is
+useful to avoid side-effects such as prompting, when the value is not
+actually being used for anything.
+
++++
+** The variable 'max-specpdl-size' has been made obsolete.
+Now 'max-lisp-eval-depth' alone is used for limiting Lisp recursion
+and stack usage. 'max-specpdl-size' is still present as a plain
+variable for compatibility but its limiting powers have been taken away.
+
* Changes in Emacs 29.1 on Non-Free Operating Systems
diff --git a/etc/NEWS.21 b/etc/NEWS.21
index 6c25a763785..a718283191b 100644
--- a/etc/NEWS.21
+++ b/etc/NEWS.21
@@ -217,7 +217,7 @@ Default is 'grow-only'.
** LessTif support.
Emacs now runs with the LessTif toolkit (see
-<http://lesstif.sourceforge.net>). You will need version 0.92.26, or later.
+<https://lesstif.sourceforge.net>). You will need version 0.92.26, or later.
** LessTif/Motif file selection dialog.
diff --git a/etc/NEWS.22 b/etc/NEWS.22
index 926b9f489ed..b4ecbe70393 100644
--- a/etc/NEWS.22
+++ b/etc/NEWS.22
@@ -1413,7 +1413,8 @@ with different file attributes in two dired buffers.
*** New Dired command 'dired-do-touch' (bound to T) changes timestamps
of marked files with the value entered in the minibuffer.
-*** In Dired, the w command now stores the current line's file name
+*** New Dired command 'dired-copy-filename-as-kill' copies file name.
+In Dired, the w command now stores the current line's file name
into the kill ring. With a zero prefix arg, it stores the absolute file name.
*** In Dired-x, Omitting files is now a minor mode, dired-omit-mode.
@@ -3539,7 +3540,7 @@ read-only on computers that are administered by someone else.
PBM and XBM images are supported out of the box. Other image formats
depend on external libraries. All of these libraries have been ported
to Windows, and can be found in both source and binary form at
-http://gnuwin32.sourceforge.net/. Note that libpng also depends on
+https://gnuwin32.sourceforge.net/. Note that libpng also depends on
zlib, and tiff depends on the version of jpeg that it was compiled
against. For additional information, see nt/INSTALL.
diff --git a/etc/NEWS.23 b/etc/NEWS.23
index ef87db79d92..5f13845dcb2 100644
--- a/etc/NEWS.23
+++ b/etc/NEWS.23
@@ -2543,6 +2543,8 @@ a list of buffers/files to search for a string/regexp.
** The new major mode 'special-mode' is intended as a parent for
major modes such as those that set the "'mode-class 'special" property.
+** New package format-spec.el provides 'format-spec'.
+
----------------------------------------------------------------------
This file is part of GNU Emacs.
diff --git a/etc/NEWS.25 b/etc/NEWS.25
index d1e43e0538e..e716f8194f5 100644
--- a/etc/NEWS.25
+++ b/etc/NEWS.25
@@ -72,7 +72,7 @@ using large fonts, at the price of a larger memory footprint.
** The version number of CC Mode has been changed from 5.33 to
5.32.99, although the software itself hasn't changed. This aims to
reduce confusion with the standalone CC Mode 5.33 (available from
-http://cc-mode.sourceforge.net), which is a more mature version than
+https://cc-mode.sourceforge.net), which is a more mature version than
the one included in Emacs 25.2.
diff --git a/etc/NEWS.26 b/etc/NEWS.26
index 50a711a0d14..9a6a7992088 100644
--- a/etc/NEWS.26
+++ b/etc/NEWS.26
@@ -1223,7 +1223,7 @@ specialized for editing freedesktop.org desktop entries.
editing Less files.
** New package 'auth-source-pass' integrates 'auth-source' with the
-password manager password-store (http://passwordstore.org).
+password manager password-store (https://passwordstore.org).
* Incompatible Lisp Changes in Emacs 26.1
diff --git a/etc/NEWS.28 b/etc/NEWS.28
index 1e8bd499b68..1edf4e85b09 100644
--- a/etc/NEWS.28
+++ b/etc/NEWS.28
@@ -16,6 +16,41 @@ You can narrow news to a specific version by calling 'view-emacs-news'
with a prefix argument or by typing 'C-u C-h C-n'.
+* Installation Changes in Emacs 28.3
+
+
+* Startup Changes in Emacs 28.3
+
+
+* Changes in Emacs 28.3
+
+
+* Editing Changes in Emacs 28.3
+
+
+* Changes in Specialized Modes and Packages in Emacs 28.3
+
+** 'native-comp-driver-options' on macOS.
+The value of 'native-comp-driver-options' has been changed to contain
+"-Wl,-w" to suppress warnings of the form
+
+ ld: warning: -undefined dynamic_lookup may not work with chained fixups
+
+emitted during native compilation on macOS 12.6 with Xcode 14.
+
+
+* New Modes and Packages in Emacs 28.3
+
+
+* Incompatible Lisp Changes in Emacs 28.3
+
+
+* Lisp Changes in Emacs 28.3
+
+
+* Changes in Emacs 28.3 on Non-Free Operating Systems
+
+
* Installation Changes in Emacs 28.2
** To install the Emacs binary in a non-standard directory, use '--bindir='.
@@ -359,7 +394,7 @@ the current buffer and the text "GNU Emacs" instead of the value of
your init file:
(setq frame-title-format '(multiple-frames "%b"
- ("" invocation-name "@" system-name)))
+ ("" invocation-name "@" system-name)))
*** New frame parameter 'drag-with-tab-line'.
This parameter, similar to 'drag-with-header-line', allows moving frames
@@ -1292,18 +1327,18 @@ comma-separated list.
*** New commands to filter the package list.
The filter commands are bound to the following keys:
-key binding
---- -------
-/ a package-menu-filter-by-archive
-/ d package-menu-filter-by-description
-/ k package-menu-filter-by-keyword
-/ N package-menu-filter-by-name-or-description
-/ n package-menu-filter-by-name
-/ s package-menu-filter-by-status
-/ v package-menu-filter-by-version
-/ m package-menu-filter-marked
-/ u package-menu-filter-upgradable
-/ / package-menu-clear-filter
+ key binding
+ --- -------
+ / a package-menu-filter-by-archive
+ / d package-menu-filter-by-description
+ / k package-menu-filter-by-keyword
+ / N package-menu-filter-by-name-or-description
+ / n package-menu-filter-by-name
+ / s package-menu-filter-by-status
+ / v package-menu-filter-by-version
+ / m package-menu-filter-marked
+ / u package-menu-filter-upgradable
+ / / package-menu-clear-filter
*** Option to automatically native-compile packages upon installation.
Customize the user option 'package-native-compile' to enable automatic
@@ -2596,7 +2631,7 @@ non-nil.
** ERC
-*** Starting with Emacs 28.1 and ERC 5.4, see the ERC-NEWS file for
+Starting with Emacs 28.1 and ERC 5.4, see the ERC-NEWS file for
user-visible changes in ERC.
** Xwidget Webkit mode
@@ -3257,12 +3292,13 @@ completing on commands from buffers in major modes derived from
MODE..., or, if it's a minor mode, when that minor mode is enabled in
the current buffer.
-Note that these forms will only have their effect if the
+Note that these forms will only have their effect for 'M-x' if the
'read-extended-command-predicate' user option is customized to call
'command-completion-default-include-p' or a similar function. The
default value of 'read-extended-command-predicate' is nil, which means
no commands that match what you have typed are excluded from being
-completion candidates.
+completion candidates. The forms will, however, be used by 'M-S-x' by
+default.
** 'define-minor-mode' now takes an ':interactive' argument.
This can be used for specifying which modes this minor mode is meant
@@ -3930,7 +3966,6 @@ and enable the MS-Windows native Input Method Editor (IME) at run
time. A companion function 'w32-get-ime-open-status' returns the
current IME activation status.
---
** On macOS, 's-<left>' and 's-<right>' are now bound to
'move-beginning-of-line' and 'move-end-of-line' respectively. The commands
to select previous/next frame are still bound to 's-~' and 's-`'.
diff --git a/etc/TODO b/etc/TODO
index 5a89c47a9c1..cd02cf70230 100644
--- a/etc/TODO
+++ b/etc/TODO
@@ -359,6 +359,17 @@ should invoke the 'shape' method. 'hbfont_shape' should be extended
to pass to 'hb_shape_full' the required array of features, as
mentioned in the above HarfBuzz discussion.
+Alternatively, stylistic sets could be a font property, or a face
+property. See this discussion:
+
+ https://lists.gnu.org/archive/html/emacs-devel/2022-09/msg01597.html
+
+For some relevant use cases, see
+
+ https://lists.gnu.org/archive/html/emacs-devel/2022-09/msg01652.html
+ https://lists.gnu.org/archive/html/emacs-devel/2022-09/msg01701.html
+ https://lists.gnu.org/archive/html/emacs-devel/2022-09/msg01772.html
+
** Concurrency
Stefan Monnier writes: "Including it as an 'experimental' compile-time
option sounds good. Of course there might still be big questions
@@ -498,7 +509,7 @@ Also for listing fonts, displaying a font as a sample, etc.
** Program Enriched mode to read and save in RTF
Is there actually a decent single definition of RTF? Maybe see info at
-http://latex2rtf.sourceforge.net/.
+https://latex2rtf.sourceforge.net/.
This task seems to be addressed by
https://savannah.nongnu.org/projects/emacs-rtf/, which is still in
@@ -875,7 +886,6 @@ window associated with that modeline.
https://lists.gnu.org/r/emacs-devel/2007-09/msg02416.html
** Random things that were planned for Emacs-24
-
Stefan Monnier writes: "Random things that cross my mind right now
that I'd like to see. Some of them from my local hacks, but it's not
obvious at all whether they'll make it."
@@ -1686,12 +1696,6 @@ and the one to use when terminating the selection.
More specifically do what's needed to make ibuffer.el the default, or
just an extension of buff-menu.el.
-** Replace linum.el with nlinum.el
-https://lists.gnu.org/r/emacs-devel/2013-08/msg00379.html
-
-(Since Emacs 26 introduced native line numbers, this item is
-probably obsolete.)
-
** Merge sendmail.el and messages.el
Probably not a complete merge, but at least arrange for messages.el to
be a derived mode of sendmail.el. Or arrange for messages.el to be
@@ -1732,11 +1736,18 @@ https://lists.gnu.org/r/emacs-devel/2012-06/msg00354.html
** Maybe replace lib-src/rcs2log with a Lisp implementation
It wouldn't have to be a complete replacement, just enough
for vc-rcs-update-changelog.
+
** Allow Emacs to use the bottom-right corner of a TTY
Emacs doesn't use the bottom-right corner of a TTY when terminfo
capability "am" (auto_right_margin) is defined. It could use the
bottom-right corner nonetheless when certain other capabilities are
defined. See bug#57607.
+
+** Replace tramp-archive.el by a native libarchive(3) implementation.
+The former is based on the GVFS archive backend, which makes it
+available on GNU/Linux only. That implementation has further
+drawbacks like it doesn't support to write into archives.
+
* Other known bugs
** 'make-frame' forgets unhandled parameters, at least for X11 frames
@@ -1758,6 +1769,26 @@ enough environment under which the fix can be tested.
The MPX code has not been tested under X toolkit or GTK+ 2.x builds
and is not expected to work there.
+** Framework for doing animations
+Emacs does animations all over the place, usually "pluse" animations.
+These currently animate by waiting for a small but fixed amount of
+time between each redisplay, which causes screen tearing by not
+synchronizing with the vertical refresh. Frame synchronization works
+by causing redisplay to delay until the next time the monitor can
+refresh; this works, but can cause substandard frame rate when
+redisplay happens less often than the monitor refreshing, as redisplay
+will have to continually wait for missed monitor refresh.
+
+The right remedy for this problem is to define a function that returns
+the amount of time remaining before the next vertical blanking period,
+and to schedule animation redisplay within that period, using the
+information provided by the _NET_WM_FRAME_DRAWN and
+_NET_WM_FRAME_TIMINGS compositor messages on X and the
+BScreen::GetMonitorInfo function on Haiku. Ideally, all features
+performing animations should be modified to use that method of
+scheduling redisplay. Examples include xref-pulse-momentarily and
+pixel-scroll-precision-start-momentum.
+
This file is part of GNU Emacs.
diff --git a/etc/images/checked.xpm b/etc/images/checked.xpm
index aefa9dd5da0..4dbcb9e6fdd 100644
--- a/etc/images/checked.xpm
+++ b/etc/images/checked.xpm
@@ -1,23 +1,4 @@
/* XPM */
-/* Copyright (C) 2010-2022 Free Software Foundation, Inc.
- *
- * Author: Chong Yidong <cyd@stupidchicken.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
static char * checked_xpm[] = {
"12 12 5 1",
" c None",
diff --git a/etc/images/gnus/gnus-pointer.xpm b/etc/images/gnus/gnus-pointer.xpm
index c47443dbb74..5328b15bedd 100644
--- a/etc/images/gnus/gnus-pointer.xpm
+++ b/etc/images/gnus/gnus-pointer.xpm
@@ -1,7 +1,7 @@
/* XPM */
-static char *gnus-pointer[] = {
+static char *gnus_pointer_xpm[] = {
/* width height num_colors chars_per_pixel */
-" 18 13 2 1",
+"18 13 2 1",
/* colors */
". c #0000ff",
"# c None s None",
@@ -19,4 +19,4 @@ static char *gnus-pointer[] = {
"###....####.######",
"###..######.######",
"###########.######"
-}; \ No newline at end of file
+};
diff --git a/etc/images/gnus/gnus.xpm b/etc/images/gnus/gnus.xpm
index b6ee4d0d733..4f46eca4fa3 100644
--- a/etc/images/gnus/gnus.xpm
+++ b/etc/images/gnus/gnus.xpm
@@ -1,7 +1,7 @@
/* XPM */
-static char *gnus[] = {
+static char *gnus_xpm[] = {
/* width height num_colors chars_per_pixel */
-" 271 273 3 1",
+"271 273 3 1",
/* colors */
". s thing c #bf9900",
"# s shadow c #ffcc00",
diff --git a/etc/images/gud/README b/etc/images/gud/README
index 5edd99e2bf7..c56c3fc0ee3 100644
--- a/etc/images/gud/README
+++ b/etc/images/gud/README
@@ -13,10 +13,10 @@ License: GNU General Public License version 3 or later (see COPYING)
Some icons are derived from Red Hat's Insight Debugger:
-<http://sourceware.org/insight/>
+<https://sourceware.org/insight/>
"Insight is a graphical user interface to GDB, the GNU Debugger"
-<http://sourceware.org/insight/aboutus.php>
+<https://sourceware.org/insight/aboutus.php>
"Insight is being released under the terms of the GNU General Public
License (GPL)"
diff --git a/etc/images/mh-logo.xpm b/etc/images/mh-logo.xpm
index 846859e0584..637c4569642 100644
--- a/etc/images/mh-logo.xpm
+++ b/etc/images/mh-logo.xpm
@@ -1,32 +1,8 @@
/* XPM */
-/* MH-E Logo
- *
- * Copyright (C) 2003-2022 Free Software Foundation, Inc.
- *
- * Author: Satyaki Das
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
-static char *mh-e[] = {
-/* width height num_colors chars_per_pixel */
-" 18 13 2 1",
-/* colors */
+static char *mh_logo_xpm[] = {
+"18 13 2 1",
"# c #666699",
". c None s None",
-/* pixels */
"........##........",
".......####.......",
"......######......",
diff --git a/etc/images/outline-close.pbm b/etc/images/outline-close.pbm
new file mode 100644
index 00000000000..b37b640b555
--- /dev/null
+++ b/etc/images/outline-close.pbm
Binary files differ
diff --git a/etc/images/outline-close.svg b/etc/images/outline-close.svg
new file mode 100644
index 00000000000..ea9157a5fb5
--- /dev/null
+++ b/etc/images/outline-close.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+<title>outline-close</title>
+<g transform="rotate(-90, 10, 10)">
+<path d="m17.5 4.75-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/>
+</g>
+</svg>
diff --git a/etc/images/outline-open.pbm b/etc/images/outline-open.pbm
new file mode 100644
index 00000000000..06b520f14c9
--- /dev/null
+++ b/etc/images/outline-open.pbm
Binary files differ
diff --git a/etc/images/outline-open.svg b/etc/images/outline-open.svg
new file mode 100644
index 00000000000..75cf6aff9f9
--- /dev/null
+++ b/etc/images/outline-open.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+<title>outline-open</title>
+<path d="m17.5 4.75-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/>
+</svg>
diff --git a/etc/images/unchecked.xpm b/etc/images/unchecked.xpm
index b758346b96f..85eec75230e 100644
--- a/etc/images/unchecked.xpm
+++ b/etc/images/unchecked.xpm
@@ -1,23 +1,4 @@
/* XPM */
-/* Copyright (C) 2010-2022 Free Software Foundation, Inc.
- *
- * Author: Chong Yidong <cyd@stupidchicken.com>
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
static char * unchecked_xpm[] = {
"12 12 5 1",
" c None",
diff --git a/etc/publicsuffix.txt b/etc/publicsuffix.txt
index 626c7993907..5676a31c3a3 100644
--- a/etc/publicsuffix.txt
+++ b/etc/publicsuffix.txt
@@ -7171,7 +7171,7 @@ org.zw
// newGTLDs
-// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2022-07-28T15:14:54Z
+// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2022-09-15T15:17:34Z
// This list is auto-generated, don't edit it manually.
// aaa : 2015-02-26 American Automobile Association, Inc.
aaa
@@ -7680,7 +7680,7 @@ cars
// casa : 2013-11-21 Registry Services, LLC
casa
-// case : 2015-09-03 Helium TLDs Ltd
+// case : 2015-09-03 Digity, LLC
case
// cash : 2014-03-06 Binky Moon, LLC
@@ -7866,7 +7866,7 @@ cool
// corsica : 2014-09-25 Collectivité de Corse
corsica
-// country : 2013-12-19 DotCountry LLC
+// country : 2013-12-19 Internet Naming Company LLC
country
// coupon : 2015-02-26 Amazon Registry Services, Inc.
@@ -8370,7 +8370,7 @@ gifts
// gives : 2014-03-06 Public Interest Registry
gives
-// giving : 2014-11-13 Giving Limited
+// giving : 2014-11-13 Public Interest Registry
giving
// glass : 2013-11-07 Binky Moon, LLC
@@ -10804,6 +10804,52 @@ s3-website.eu-west-2.amazonaws.com
s3-website.eu-west-3.amazonaws.com
s3-website.us-east-2.amazonaws.com
+// AWS Cloud9 : https://aws.amazon.com/cloud9/
+// Submitted by: AWS Security <psl-maintainers@amazon.com>
+// Reference: 2b6dfa9a-3a7f-4367-b2e7-0321e77c0d59
+vfs.cloud9.af-south-1.amazonaws.com
+webview-assets.cloud9.af-south-1.amazonaws.com
+vfs.cloud9.ap-east-1.amazonaws.com
+webview-assets.cloud9.ap-east-1.amazonaws.com
+vfs.cloud9.ap-northeast-1.amazonaws.com
+webview-assets.cloud9.ap-northeast-1.amazonaws.com
+vfs.cloud9.ap-northeast-2.amazonaws.com
+webview-assets.cloud9.ap-northeast-2.amazonaws.com
+vfs.cloud9.ap-northeast-3.amazonaws.com
+webview-assets.cloud9.ap-northeast-3.amazonaws.com
+vfs.cloud9.ap-south-1.amazonaws.com
+webview-assets.cloud9.ap-south-1.amazonaws.com
+vfs.cloud9.ap-southeast-1.amazonaws.com
+webview-assets.cloud9.ap-southeast-1.amazonaws.com
+vfs.cloud9.ap-southeast-2.amazonaws.com
+webview-assets.cloud9.ap-southeast-2.amazonaws.com
+vfs.cloud9.ca-central-1.amazonaws.com
+webview-assets.cloud9.ca-central-1.amazonaws.com
+vfs.cloud9.eu-central-1.amazonaws.com
+webview-assets.cloud9.eu-central-1.amazonaws.com
+vfs.cloud9.eu-north-1.amazonaws.com
+webview-assets.cloud9.eu-north-1.amazonaws.com
+vfs.cloud9.eu-south-1.amazonaws.com
+webview-assets.cloud9.eu-south-1.amazonaws.com
+vfs.cloud9.eu-west-1.amazonaws.com
+webview-assets.cloud9.eu-west-1.amazonaws.com
+vfs.cloud9.eu-west-2.amazonaws.com
+webview-assets.cloud9.eu-west-2.amazonaws.com
+vfs.cloud9.eu-west-3.amazonaws.com
+webview-assets.cloud9.eu-west-3.amazonaws.com
+vfs.cloud9.me-south-1.amazonaws.com
+webview-assets.cloud9.me-south-1.amazonaws.com
+vfs.cloud9.sa-east-1.amazonaws.com
+webview-assets.cloud9.sa-east-1.amazonaws.com
+vfs.cloud9.us-east-1.amazonaws.com
+webview-assets.cloud9.us-east-1.amazonaws.com
+vfs.cloud9.us-east-2.amazonaws.com
+webview-assets.cloud9.us-east-2.amazonaws.com
+vfs.cloud9.us-west-1.amazonaws.com
+webview-assets.cloud9.us-west-1.amazonaws.com
+vfs.cloud9.us-west-2.amazonaws.com
+webview-assets.cloud9.us-west-2.amazonaws.com
+
// Amune : https://amune.org/
// Submitted by Team Amune <cert@amune.org>
t3l3p0rt.net
@@ -12874,6 +12920,7 @@ azure-mobile.net
cloudapp.net
azurestaticapps.net
1.azurestaticapps.net
+2.azurestaticapps.net
centralus.azurestaticapps.net
eastasia.azurestaticapps.net
eastus2.azurestaticapps.net
diff --git a/etc/srecode/ede-autoconf.srt b/etc/srecode/ede-autoconf.srt
index ecca7afd007..51656eb73c4 100644
--- a/etc/srecode/ede-autoconf.srt
+++ b/etc/srecode/ede-autoconf.srt
@@ -38,7 +38,7 @@ template ede-empty :project
{{comment_prefix}} by EDE when this file is updated.
{{comment_prefix}}
{{comment_prefix}} EDE is the Emacs Development Environment.
-{{comment_prefix}} http://cedet.sourceforge.net/ede.shtml
+{{comment_prefix}} https://cedet.sourceforge.net/ede.shtml
{{comment_prefix}}
{{comment_prefix}} Process this file with autoconf to produce a configure script
diff --git a/etc/srecode/ede-make.srt b/etc/srecode/ede-make.srt
index cde1690f54f..c01054e0420 100644
--- a/etc/srecode/ede-make.srt
+++ b/etc/srecode/ede-make.srt
@@ -34,7 +34,7 @@ template ede-empty :file :project
#
# DO NOT MODIFY THIS FILE OR YOUR CHANGES MAY BE LOST.
# EDE is the Emacs Development Environment.
-# http://cedet.sourceforge.net/ede.shtml
+# https://cedet.sourceforge.net/ede.shtml
#
----
@@ -58,7 +58,7 @@ template ede-empty :file
#
# DO NOT MODIFY THIS FILE OR YOUR CHANGES MAY BE LOST.
# EDE is the Emacs Development Environment.
-# http://cedet.sourceforge.net/ede.shtml
+# https://cedet.sourceforge.net/ede.shtml
ARDUINO_DIR = {{ARDUINO_HOME}}
diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el
index ba83a0578cd..6ad84055595 100644
--- a/etc/themes/adwaita-theme.el
+++ b/etc/themes/adwaita-theme.el
@@ -21,10 +21,13 @@
;;; Code:
+;;;###theme-autoload
(deftheme adwaita
"Face colors similar to the default theme of Gnome 3 (Adwaita).
The colors are chosen to match Adwaita window decorations and the
-default look of the Gnome 3 desktop.")
+default look of the Gnome 3 desktop."
+ :background-mode 'light
+ :kind 'color-scheme)
(let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces
diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el
index 8f19147f916..48ed9ba061d 100644
--- a/etc/themes/deeper-blue-theme.el
+++ b/etc/themes/deeper-blue-theme.el
@@ -21,8 +21,11 @@
;;; Code:
+;;;###theme-autoload
(deftheme deeper-blue
- "Face colors using a deep blue background.")
+ "Face colors using a deep blue background."
+ :background-mode 'dark
+ :kind 'color-scheme)
(let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces
diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el
index d53c075d923..fe44d520cca 100644
--- a/etc/themes/dichromacy-theme.el
+++ b/etc/themes/dichromacy-theme.el
@@ -21,6 +21,7 @@
;;; Code:
+;;;###theme-autoload
(deftheme dichromacy
"Face colors suitable for red/green color-blind users.
The color palette is from B. Wong, Nature Methods 8, 441 (2011).
@@ -28,7 +29,9 @@ It is intended to provide good variability while being easily
differentiated by individuals with protanopia or deuteranopia.
Basic, Font Lock, Isearch, Gnus, Message, Flyspell, and
-Ansi-Color faces are included.")
+Ansi-Color faces are included."
+ :background-mode 'light
+ :kind 'color-scheme)
(let ((class '((class color) (min-colors 89)))
(orange "#e69f00")
diff --git a/etc/themes/leuven-dark-theme.el b/etc/themes/leuven-dark-theme.el
index 0e162c8bab9..08978a26682 100644
--- a/etc/themes/leuven-dark-theme.el
+++ b/etc/themes/leuven-dark-theme.el
@@ -5,7 +5,7 @@
;; Author: Fabrice Niessen <(concat "fniessen" at-sign "pirilampo.org")>
;; Contributor: Thibault Polge <(concat "thibault" at-sign "thb.lt")>
;; URL: https://github.com/fniessen/emacs-leuven-dark-theme
-;; Version: 20220202.1126
+;; Version: 20221010.1208
;; Keywords: color theme
;; This file is part of GNU Emacs.
@@ -93,11 +93,15 @@ CONTROL can be a number, nil, or t. When t, use DEFAULT-HEIGHT."
;;; Theme Faces.
+;;;###theme-autoload
(deftheme leuven-dark
"Face colors with a light background.
Basic, Font Lock, Isearch, Gnus, Message, Org mode, Diff, Ediff,
Flyspell, Semantic, and Ansi-Color faces are included -- and much
-more...")
+more..."
+ :background-mode 'dark
+ :family 'leuven
+ :kind 'color-scheme)
(let ((class '((class color) (min-colors 89)))
diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el
index d9a8d5391ae..e712a79adf1 100644
--- a/etc/themes/leuven-theme.el
+++ b/etc/themes/leuven-theme.el
@@ -4,7 +4,7 @@
;; Author: Fabrice Niessen <(concat "fniessen" at-sign "pirilampo.org")>
;; URL: https://github.com/fniessen/emacs-leuven-theme
-;; Version: 20200513.1928
+;; Version: 20221010.1209
;; Keywords: color theme
;; This file is part of GNU Emacs.
@@ -74,11 +74,15 @@ CONTROL can be a number, nil, or t. When t, use DEFAULT-HEIGHT."
;;; Theme Faces.
+;;;###theme-autoload
(deftheme leuven
"Face colors with a light background.
Basic, Font Lock, Isearch, Gnus, Message, Org mode, Diff, Ediff,
Flyspell, Semantic, and Ansi-Color faces are included -- and much
-more...")
+more..."
+ :background-mode 'light
+ :kind 'color-scheme
+ :family 'leuven)
(let ((class '((class color) (min-colors 89)))
diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el
index eeca46210cc..808fcbfeb2d 100644
--- a/etc/themes/light-blue-theme.el
+++ b/etc/themes/light-blue-theme.el
@@ -26,8 +26,11 @@
;;; Code:
+;;;###theme-autoload
(deftheme light-blue
- "Face colors utilizing a light blue background.")
+ "Face colors utilizing a light blue background."
+ :background-mode 'light
+ :kind 'color-scheme)
(make-obsolete 'light-blue nil "29.1")
diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el
index af5576386c6..f9aaa97c258 100644
--- a/etc/themes/manoj-dark-theme.el
+++ b/etc/themes/manoj-dark-theme.el
@@ -64,10 +64,13 @@
;;; Code:
+;;;###theme-autoload
(deftheme manoj-dark
"Very high contrast faces with a black background.
This theme avoids subtle color variations, while avoiding the
-jarring angry fruit salad look to reduce eye fatigue.")
+jarring angry fruit salad look to reduce eye fatigue."
+ :background-mode 'dark
+ :kind 'color-scheme)
(custom-theme-set-faces
'manoj-dark
diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el
index 55186384ad1..3fd6cdb5afb 100644
--- a/etc/themes/misterioso-theme.el
+++ b/etc/themes/misterioso-theme.el
@@ -21,8 +21,11 @@
;;; Code:
+;;;###theme-autoload
(deftheme misterioso
- "Predominantly blue/cyan faces on a dark cyan background.")
+ "Predominantly blue/cyan faces on a dark cyan background."
+ :background-mode 'dark
+ :kind 'color-scheme)
(let ((class '((class color) (min-colors 89))))
diff --git a/etc/themes/modus-operandi-theme.el b/etc/themes/modus-operandi-theme.el
index fd7ffff98ff..0f0630a6d1d 100644
--- a/etc/themes/modus-operandi-theme.el
+++ b/etc/themes/modus-operandi-theme.el
@@ -6,7 +6,7 @@
;; Maintainer: Modus-Themes Development <~protesilaos/modus-themes@lists.sr.ht>
;; URL: https://git.sr.ht/~protesilaos/modus-themes
;; Mailing-List: https://lists.sr.ht/~protesilaos/modus-themes
-;; Version: 2.6.0
+;; Version: 2.7.1
;; Package-Requires: ((emacs "27.1"))
;; Keywords: faces, theme, accessibility
@@ -71,4 +71,6 @@ which corresponds to a minimum contrast in relative luminance of
(provide-theme 'modus-operandi))
+;;;###theme-autoload (put 'modus-operandi 'theme-properties '(:background-mode light :kind color-scheme :family modus))
+
;;; modus-operandi-theme.el ends here
diff --git a/etc/themes/modus-themes.el b/etc/themes/modus-themes.el
index c4edb1efcb8..d5e1b0a120b 100644
--- a/etc/themes/modus-themes.el
+++ b/etc/themes/modus-themes.el
@@ -6,7 +6,7 @@
;; Maintainer: Modus-Themes Development <~protesilaos/modus-themes@lists.sr.ht>
;; URL: https://git.sr.ht/~protesilaos/modus-themes
;; Mailing-List: https://lists.sr.ht/~protesilaos/modus-themes
-;; Version: 2.6.0
+;; Version: 2.7.1
;; Package-Requires: ((emacs "27.1"))
;; Keywords: faces, theme, accessibility
@@ -109,7 +109,7 @@ cover the blue-cyan-magenta side of the spectrum."
:prefix "modus-themes-"
:tag "Modus Themes Faces")
-(defvar modus-themes--version "2.6.0"
+(defvar modus-themes--version "2.7.0"
"Current version of the Modus themes.
The version either is the last tagged release, such as '1.0.0',
@@ -634,7 +634,7 @@ symbol and the latter as a string.")
(bg-diff-focus-added . "#1d3c25") (fg-diff-focus-added . "#b4ddb4")
(bg-diff-focus-added-deuteran . "#003959") (fg-diff-focus-added-deuteran . "#bfe4ff")
(bg-diff-focus-changed . "#424200") (fg-diff-focus-changed . "#d0daaf")
- (bg-diff-focus-removed . "#500f29") (fg-diff-focus-removed . "#eebdba")
+ (bg-diff-focus-removed . "#601f29") (fg-diff-focus-removed . "#eebdba")
(bg-mark-sel . "#002f2f") (fg-mark-sel . "#60cfa2")
(bg-mark-del . "#5a0000") (fg-mark-del . "#ff99aa")
@@ -1435,7 +1435,7 @@ By default, customizing a theme-related user option through the
Custom interfaces or with `customize-set-variable' will not
reload the currently active Modus theme.
-Enable this behaviour by setting this variable to nil."
+Enable this behavior by setting this variable to nil."
:group 'modus-themes
:package-version '(modus-themes . "1.5.0")
:version "28.1"
@@ -2270,7 +2270,7 @@ follows (order is not significant):
The `popup' key takes the same values as `selection'.
-Apart from specfying each key separately, a fallback list is
+Apart from specifying each key separately, a fallback list is
accepted. This is only useful when the desired aesthetic is the
same across all keys that are not explicitly referenced. For
example, this:
@@ -4387,6 +4387,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(help-key-binding ((,class :inherit modus-themes-key-binding)))
`(homoglyph ((,class :foreground ,red-alt-faint)))
`(ibuffer-locked-buffer ((,class :foreground ,yellow-alt-other-faint)))
+ `(icon-button ((,class :inherit modus-themes-box-button)))
`(italic ((,class :slant italic)))
`(nobreak-hyphen ((,class :foreground ,fg-escape-char-construct)))
`(nobreak-space ((,class :foreground ,fg-escape-char-construct :underline t)))
@@ -4396,6 +4397,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(mm-uu-extract ((,class :background ,bg-dim :foreground ,fg-special-mild)))
`(next-error ((,class :inherit modus-themes-subtle-red :extend t)))
`(pgtk-im-0 ((,class :inherit modus-themes-refine-cyan)))
+ `(read-multiple-choice-face ((,class :inherit (bold modus-themes-mark-alt))))
`(rectangle-preview ((,class :inherit modus-themes-special-warm)))
`(region ((,class ,@(modus-themes--region bg-region fg-main
bg-hl-alt-intense bg-region-accent
@@ -4532,9 +4534,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(font-latex-string-face ((,class :inherit font-lock-string-face)))
`(font-latex-subscript-face ((,class :height 0.95)))
`(font-latex-superscript-face ((,class :height 0.95)))
+ `(font-latex-underline-face ((,class :inherit underline)))
`(font-latex-verbatim-face ((,class :inherit modus-themes-markup-verbatim)))
`(font-latex-warning-face ((,class :inherit font-lock-warning-face)))
- `(tex-match ((,class :foreground ,blue-alt-other)))
`(tex-verbatim ((,class :inherit modus-themes-markup-verbatim)))
`(texinfo-heading ((,class :foreground ,magenta)))
`(TeX-error-description-error ((,class :inherit error)))
@@ -4657,6 +4659,18 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(calibredb-mark-face ((,class :inherit modus-themes-mark-sel)))
`(calibredb-size-face (( )))
`(calibredb-tag-face ((,class :foreground ,magenta-alt-faint)))
+;;;;; centaur-tabs
+ `(centaur-tabs-active-bar-face ((,class :background ,blue-active)))
+ `(centaur-tabs-close-mouse-face ((,class :inherit bold :foreground ,red-active :underline t)))
+ `(centaur-tabs-close-selected ((,class :inherit centaur-tabs-selected)))
+ `(centaur-tabs-close-unselected ((,class :inherit centaur-tabs-unselected)))
+ `(centaur-tabs-modified-marker-selected ((,class :inherit centaur-tabs-selected)))
+ `(centaur-tabs-modified-marker-unselected ((,class :inherit centaur-tabs-unselected)))
+ `(centaur-tabs-default ((,class :background ,bg-main)))
+ `(centaur-tabs-selected ((,class :inherit modus-themes-tab-active)))
+ `(centaur-tabs-selected-modified ((,class :inherit (italic centaur-tabs-selected))))
+ `(centaur-tabs-unselected ((,class :inherit modus-themes-tab-inactive)))
+ `(centaur-tabs-unselected-modified ((,class :inherit (italic centaur-tabs-unselected))))
;;;;; cfrs
`(cfrs-border-color ((,class :background ,fg-window-divider-inner)))
;;;;; change-log and log-view (`vc-print-log' and `vc-print-root-log')
@@ -4669,6 +4683,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(change-log-list ((,class :foreground ,magenta-alt)))
`(change-log-name ((,class :foreground ,magenta-alt-other)))
`(log-edit-header ((,class :foreground ,fg-special-warm)))
+ `(log-edit-headers-separator ((,class :height 1 :background ,fg-window-divider-inner :extend t)))
`(log-edit-summary ((,class :inherit bold :foreground ,blue)))
`(log-edit-unknown-header ((,class :inherit shadow)))
`(log-view-commit-body ((,class :foreground ,blue-nuanced-fg)))
@@ -4743,6 +4758,8 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(company-preview-common ((,class :inherit company-echo-common)))
`(company-preview-search ((,class :inherit modus-themes-special-calm)))
`(company-template-field ((,class :inherit modus-themes-intense-magenta)))
+ `(company-scrollbar-bg ((,class :background ,bg-active)))
+ `(company-scrollbar-fg ((,class :background ,fg-active)))
`(company-tooltip ((,class :background ,bg-alt)))
`(company-tooltip-annotation ((,class :inherit completions-annotations)))
`(company-tooltip-common ((,class :inherit company-echo-common)))
@@ -4824,6 +4841,13 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(cperl-nonoverridable-face ((,class :foreground unspecified)))
`(cperl-array-face ((,class :inherit font-lock-keyword-face)))
`(cperl-hash-face ((,class :inherit font-lock-variable-name-face)))
+;;;;; crontab-mode
+ `(crontab-minute ((,class :foreground ,blue-alt)))
+ `(crontab-hour ((,class :foreground ,magenta-alt-other)))
+ `(crontab-month-day ((,class :foreground ,magenta-alt)))
+ `(crontab-month ((,class :foreground ,blue)))
+ `(crontab-week-day ((,class :foreground ,cyan)))
+ `(crontab-predefined ((,class :foreground ,blue-alt)))
;;;;; css-mode
`(css-property ((,class :inherit font-lock-type-face)))
`(css-selector ((,class :inherit font-lock-keyword-face)))
@@ -5041,7 +5065,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(diredp-tagged-autofile-name ((,class :inherit modus-themes-refine-magenta)))
`(diredp-write-priv ((,class :foreground ,cyan)))
;;;;; display-fill-column-indicator-mode
- `(fill-column-indicator ((,class :height 1 :background ,bg-inactive :foreground ,bg-inactive)))
+ `(fill-column-indicator ((,class :height 1 :background ,bg-region :foreground ,bg-region)))
;;;;; doom-modeline
`(doom-modeline-bar ((,class :inherit modus-themes-active-blue)))
`(doom-modeline-bar-inactive ((,class :background ,fg-inactive :foreground ,bg-main)))
@@ -5608,7 +5632,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(gnus-summary-low-read ((,class :inherit italic :foreground ,fg-alt)))
`(gnus-summary-low-ticked ((,class :inherit italic :foreground ,red-refine-fg)))
`(gnus-summary-low-undownloaded ((,class :inherit italic :foreground ,yellow-refine-fg)))
- `(gnus-summary-low-unread ((,class :inherit bold :foreground ,fg-special-cold)))
+ `(gnus-summary-low-unread ((,class :inherit italic :foreground ,fg-special-cold)))
`(gnus-summary-normal-ancient ((,class :foreground ,fg-special-calm)))
`(gnus-summary-normal-read ((,class :inherit shadow)))
`(gnus-summary-normal-ticked ((,class :foreground ,red-alt-other)))
@@ -6723,6 +6747,9 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(powerline-evil-operator-face ((,class :inherit modus-themes-active-yellow)))
`(powerline-evil-replace-face ((,class :inherit modus-themes-active-red)))
`(powerline-evil-visual-face ((,class :inherit modus-themes-active-cyan)))
+;;;;; prescient
+ `(prescient-primary-highlight ((,class :inherit modus-themes-completion-match-0)))
+ `(prescient-secondary-highlight ((,class :inherit modus-themes-completion-match-1)))
;;;;; proced
`(proced-mark ((,class :inherit modus-themes-mark-symbol)))
`(proced-marked ((,class :inherit modus-themes-mark-alt)))
@@ -6841,9 +6868,6 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(selectrum-mouse-highlight ((,class :inherit highlight)))
`(selectrum-quick-keys-highlight ((,class :inherit bold :background ,bg-char-0)))
`(selectrum-quick-keys-match ((,class :inherit bold :background ,bg-char-1)))
-;;;;; selectrum-prescient
- `(selectrum-prescient-primary-highlight ((,class :inherit modus-themes-completion-match-0)))
- `(selectrum-prescient-secondary-highlight ((,class :inherit modus-themes-completion-match-1)))
;;;;; semantic
`(semantic-complete-inline-face ((,class :foreground ,fg-special-warm :underline t)))
`(semantic-decoration-on-fileless-includes ((,class :inherit modus-themes-refine-green)))
@@ -6988,6 +7012,8 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(speedbar-selected-face ((,class :inherit bold :foreground ,cyan)))
`(speedbar-separator-face ((,class :inherit modus-themes-intense-neutral)))
`(speedbar-tag-face ((,class :foreground ,yellow-alt-other)))
+;;;;; spell-fu
+ `(spell-fu-incorrect-face ((,class :inherit modus-themes-lang-error)))
;;;;; stripes
`(stripes ((,class :background ,bg-alt)))
;;;;; suggest
@@ -7526,7 +7552,7 @@ by virtue of calling either of `modus-themes-load-operandi' and
`(xterm-color-names-bright ["gray35" ,red-alt ,green-alt ,yellow-alt ,blue-alt ,magenta-alt ,cyan-alt "white"])
(if (or (eq modus-themes-org-blocks 'tinted-background)
(eq modus-themes-org-blocks 'rainbow))
- `(org-src-block-faces ; TODO this list should be expanded
+ `(org-src-block-faces
`(("emacs-lisp" modus-themes-nuanced-magenta)
("elisp" modus-themes-nuanced-magenta)
("clojure" modus-themes-nuanced-magenta)
diff --git a/etc/themes/modus-vivendi-theme.el b/etc/themes/modus-vivendi-theme.el
index ba75a2527da..02c2d9e129a 100644
--- a/etc/themes/modus-vivendi-theme.el
+++ b/etc/themes/modus-vivendi-theme.el
@@ -6,7 +6,7 @@
;; Maintainer: Modus-Themes Development <~protesilaos/modus-themes@lists.sr.ht>
;; URL: https://git.sr.ht/~protesilaos/modus-themes
;; Mailing-List: https://lists.sr.ht/~protesilaos/modus-themes
-;; Version: 2.6.0
+;; Version: 2.7.1
;; Package-Requires: ((emacs "27.1"))
;; Keywords: faces, theme, accessibility
@@ -71,4 +71,6 @@ which corresponds to a minimum contrast in relative luminance of
(provide-theme 'modus-vivendi))
+;;;###theme-autoload (put 'modus-vivendi 'theme-properties '(:background-mode dark :kind color-scheme :family modus))
+
;;; modus-vivendi-theme.el ends here
diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el
index ef00d2ac49f..85995e4e995 100644
--- a/etc/themes/tango-dark-theme.el
+++ b/etc/themes/tango-dark-theme.el
@@ -27,10 +27,15 @@
;;; Code:
+;;;###theme-autoload
(deftheme tango-dark
"Face colors using the Tango palette (dark background).
Basic, Font Lock, Isearch, Gnus, Message, Ediff, Flyspell,
-Semantic, and Ansi-Color faces are included.")
+Semantic, and Ansi-Color faces are included."
+ :background-mode 'dark
+ :kind 'color-scheme
+ :family 'tango)
+
(let ((class '((class color) (min-colors 89)))
;; Tango palette colors.
diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el
index ecbbf037536..2ac1b42294b 100644
--- a/etc/themes/tango-theme.el
+++ b/etc/themes/tango-theme.el
@@ -27,10 +27,14 @@
;;; Code:
+;;;###theme-autoload
(deftheme tango
"Face colors using the Tango palette (light background).
Basic, Font Lock, Isearch, Gnus, Message, Ediff, Flyspell,
-Semantic, and Ansi-Color faces are included.")
+Semantic, and Ansi-Color faces are included."
+ :background-mode 'light
+ :kind 'color-scheme
+ :family 'tango)
(let ((class '((class color) (min-colors 89)))
;; Tango palette colors.
diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el
index a88ad75520b..6b1e865e427 100644
--- a/etc/themes/tsdh-dark-theme.el
+++ b/etc/themes/tsdh-dark-theme.el
@@ -19,8 +19,12 @@
;;; Code:
+;;;###theme-autoload
(deftheme tsdh-dark
- "A dark theme used and created by Tassilo Horn.")
+ "A dark theme used and created by Tassilo Horn."
+ :background-mode 'dark
+ :kind 'color-scheme
+ :family 'tsdh)
(custom-theme-set-faces
'tsdh-dark
diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el
index d9d09b702b7..ac964d66d67 100644
--- a/etc/themes/tsdh-light-theme.el
+++ b/etc/themes/tsdh-light-theme.el
@@ -19,9 +19,13 @@
;;; Code:
+;;;###theme-autoload
(deftheme tsdh-light
"A light Emacs theme.
-Used and created by Tassilo Horn.")
+Used and created by Tassilo Horn."
+ :background-mode 'light
+ :kind 'color-scheme
+ :family 'tsdh)
(custom-theme-set-faces
'tsdh-light
diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el
index c56c8a2d8a4..20e7bbbac29 100644
--- a/etc/themes/wheatgrass-theme.el
+++ b/etc/themes/wheatgrass-theme.el
@@ -19,11 +19,14 @@
;;; Code:
+;;;###theme-autoload
(deftheme wheatgrass
"High-contrast green/blue/brown faces on a black background.
Basic, Font Lock, Isearch, Gnus, and Message faces are included.
The default face foreground is wheat, with other faces in shades
-of green, brown, and blue.")
+of green, brown, and blue."
+ :background-mode 'dark
+ :kind 'color-scheme)
(let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces
diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el
index f21b18b421d..2f86234b32a 100644
--- a/etc/themes/whiteboard-theme.el
+++ b/etc/themes/whiteboard-theme.el
@@ -21,8 +21,11 @@
;;; Code:
+;;;###theme-autoload
(deftheme whiteboard
- "Face colors similar to markers on a whiteboard.")
+ "Face colors similar to markers on a whiteboard."
+ :background-mode 'light
+ :kind 'color-scheme)
(let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces
diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el
index d9fab8ac782..9bb026ead14 100644
--- a/etc/themes/wombat-theme.el
+++ b/etc/themes/wombat-theme.el
@@ -21,11 +21,14 @@
;;; Code:
+;;;###theme-autoload
(deftheme wombat
"Medium-contrast faces with a dark gray background.
Adapted, with permission, from a Vim color scheme by Lars H. Nielsen.
Basic, Font Lock, Isearch, Gnus, Message, and Ansi-Color faces
-are included.")
+are included."
+ :background-mode 'dark
+ :kind 'color-scheme)
(let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces
diff --git a/etc/tutorials/TUTORIAL.translators b/etc/tutorials/TUTORIAL.translators
index 891b6a16824..64d71b61e84 100644
--- a/etc/tutorials/TUTORIAL.translators
+++ b/etc/tutorials/TUTORIAL.translators
@@ -90,6 +90,10 @@ Maintainer: Mats Lidell <matsl@contactor.se>
Author: Virach Sornlertlamvanich <virach@nectec.or.th>
Maintainer: Virach Sornlertlamvanich <virach@nectec.or.th>
+* TUTORIAL.uk:
+Author: Denys Nykula <vegan@libre.net.ua>
+Maintainer: Denys Nykula <vegan@libre.net.ua>
+
* TUTORIAL.zh:
Author: Chao-Hong Liu <chliu@gnu.org>
Maintainer: Chao-Hong Liu <chliu@gnu.org>
diff --git a/etc/tutorials/TUTORIAL.uk b/etc/tutorials/TUTORIAL.uk
new file mode 100644
index 00000000000..16190afe3a3
--- /dev/null
+++ b/etc/tutorials/TUTORIAL.uk
@@ -0,0 +1,1150 @@
+Посібник Emacs. Умови копіювання в кінці.
+
+Команди Emacs передбачають використання клавіші CONTROL (часто
+підписаної CTRL чи CTL) або клавіші META (зазвичай підписаної ALT).
+Щоб не писати цього щоразу повністю, використовуємо такі скорочення:
+
+ C-<симв> означає затиснути клавішу CONTROL і натиснути клавішу
+ <симв>. Тобто C-f — це затиснути CONTROL і натиснути f.
+
+ M-<симв> означає затиснути клавішу META чи ALT і натиснути <симв>.
+ Якщо не маєте клавіші META чи ALT, натисніть по черзі
+ клавіші ESC та <симв>. Клавішу ESC ми позначаємо <ESC>.
+
+Щоб редагувати український текст в Emacs, перемкніться на англійську
+розкладку й наберіть C-\ — це активує український режим введення
+Emacs, у якому працюватимуть як слід усі описані в посібнику команди.
+Щоб знову вводити англійські символи, повторіть C-\.
+
+Зауважте: щоб завершити сеанс Emacs, наберіть C-x C-c. (Два символи.)
+Щоб скасувати частково введену команду, наберіть C-g. Щоб закрити
+посібник, наберіть C-x k, а тоді при запиті натисніть <Return> (цю
+клавішу може бути підписано Enter). Абзаци, що містять „»»“ на
+початку, — це вказівки, які вам слід виконати, щоб спробувати
+використати ту чи іншу команду. Наприклад:
+<<Програма help-with-tutorial огортає наступний рядок відступами>>
+[Кілька навмисне порожніх рядків. Скоро зрозумієте, навіщо.]
+»» Прямо зараз наберіть C-v (view — переглянути), щоб прогорнути
+ посібник униз. (Затисніть клавішу CONTROL і наберіть v.)
+ Робіть так щоразу, коли дочитуєте до кінця екрана.
+
+Як бачите, гортається не цілий екран, а на два рядки менше; це
+допомагає не губитись, коли читаєте довгі тексти.
+
+Це одноразова, трошки адаптована спеціально для вас копія тексту
+посібника Emacs. Будемо пропонувати вам випробовувати прямо на цьому
+тексті різні команди, які його змінюватимуть. Якщо зміните цей текст
+самостійно навіть без наших вказівок — чудово, це називається
+«редагування» й саме для цього створено Emacs.
+
+Перш за все навчимось пересуватися текстом. Ви вже знаєте, як
+прогорнути один екран уперед: C-v. Прогорнути один екран назад — це
+M-v (затисніть клавішу META й наберіть v — або наберіть <ESC>v, якщо
+не маєте ні клавіші META, ні клавіші ALT).
+
+»» Спробуйте набрати M-v й тоді C-v кілька разів по черзі.
+
+Якщо знаєте інші способи гортати текст, то можете, звісно,
+застосовувати і їх.
+
+* ПІДСУМОК
+----------
+
+Наступні команди допомагають гортати екрани тексту:
+
+ C-v (View — переглянути.)
+ Перейти на наступний екран.
+
+ M-v Перейти на попередній екран.
+
+ C-l (Clear — очистити.)
+ Очистити екран і вивести текст заново, центруючи екран
+ на тексті біля курсора. (Це CONTROL-L, не CONTROL-1.)
+
+»» Знайдіть курсор і зверніть увагу, який біля нього текст. Наберіть
+ C-l. Знайдіть, куди змістився курсор, і зауважте, що біля курсора
+ досі той самий текст, просто він тепер у центрі екрана. Якщо знов
+ натиснете C-l, цей самий текст посунеться догори екрана. Натисніть
+ C-l іще раз, і він посунеться донизу.
+
+Можете також гортати екрани клавішами PageUp і PageDn, якщо ваш
+термінал їх має. Але з C-v та M-v ви редагуватимете спритніше.
+
+* ОСНОВИ КЕРУВАННЯ КУРСОРОМ
+---------------------------
+
+Гортати екран за екраном — це вже непогано, але як перейти до
+конкретного місця в тексті на екрані?
+
+Є кілька способів. Можна рухатись клавішами стрілок, але зручніше
+тримати руки в стандартному положенні й використовувати команди C-p
+(previous — попередній), C-b (backward — назад), C-f (forward —
+уперед) і C-n (next — наступний). Ці символи рівнозначні
+чотирьом клавішам стрілок:
+
+ Попередній рядок, C-p
+ :
+ :
+ Назад, C-b .... Де курсор зараз .... Уперед, C-f
+ :
+ :
+ Наступний рядок, C-n
+
+»» Посуньте курсор до рядка посередині рисунка вгорі за допомогою C-n
+ та C-p. Тоді наберіть C-l, щоб центрувати екран на рисунку.
+
+Літери в скороченнях Emacs легко запам'ятати за відповідними їм
+англійськими словами, як зазначено вгорі. Ці основні команди руху
+курсора ви будете використовувати весь час.
+
+»» Наберіть C-n кілька разів, щоб посунути курсор до цього рядка.
+
+»» Посуньте курсор до якого-небудь слова в рядку, набравши C-f
+ декілька разів, а тоді поверніться вгору кількома натисками C-p.
+ Зауважте, як C-p поводиться, коли курсор не на початку рядка.
+
+Кожен рядок тексту закінчується символом нового рядка: цей символ
+технічно відділяє рядок від наступного. (Зазвичай останній рядок у
+файлі теж закінчується символом нового рядка, проте Emacs цього не
+вимагає.)
+
+»» Спробуйте C-b на початку рядка. Курсор має зміститись у кінець
+ попереднього рядка, бо рух назад (backward) «проїде» по символу
+ нового рядка.
+
+C-f — рух уперед (forward) — уміє «їздити» по символах нового рядка
+так само, як і C-b.
+
+»» Наберіть C-b іще кілька разів, щоб відчути, яким чином рухається
+ курсор. Тоді поверніться в кінець того рядка, з якого почали рух:
+ кілька разів наберіть C-f. Тоді перейдіть іще одним C-f до
+ наступного рядка.
+
+Коли ваш рух перетинає верх чи низ екрана, текст із-за краю
+посувається на екран. Це називається «гортання», або scrolling.
+Таким чином курсор, куди б у тексті ви його не спрямували, залишається
+в межах екрана Emacs.
+
+»» Спробуйте посунути курсор за нижню межу екрана кількома натисками
+ C-n — і зверніть увагу на поведінку.
+
+Коли рухатися символами надто повільно, рухайтеся словами. M-f
+(META-f) посуває курсор через ціле слово вперед (forward), а M-b —
+через слово назад (backward).
+
+»» Наберіть M-f і M-b по кілька разів.
+
+Коли ви посеред слова, M-f посуває курсор до кінця слова. Коли ви на
+пробілі, M-f посуває курсор у кінець наступного слова. M-b працює
+аналогічно в зворотному напрямі.
+
+»» Наберіть іще кілька M-f і M-b, розділяючи їх натисками C-f і C-b,
+ щоб поспостерігати за поведінкою M-f і M-b залежно від перебування
+ курсора в різних місцях усередині слів і між словами.
+
+Простежте паралелі між C-f і C-b з одного боку та M-f і M-b з іншого.
+Часто Meta-символи використовуються для роботи з одиницями,
+визначеними мовою: зі словами, реченнями, абзацами. Тоді як
+Control-символи працюють із низькорівневими одиницями, без огляду на
+редаговане середовище: з символами, рядками тощо.
+
+Ця паралель стосується також рядків і речень: C-a та C-e посувають до
+початку чи кінця рядка, тоді як M-a та M-e посувають до початку чи
+кінця речення.
+
+»» Наберіть C-a кілька разів, тоді наберіть C-e кілька разів.
+ Наберіть M-a кілька разів, тоді наберіть M-e кілька разів.
+
+Зверніть увагу на те, як повторні натиски C-a не викликають нових
+рухів, а от повтори M-a щоразу рухають вас на одне речення назад.
+Поведінка дещо різна, втім природна для кожного контексту.
+
+Координати курсора в тексті називаються «точкою». Іншими словами,
+курсор позначає на екрані поточну точку в тексті.
+
+Ось підсумок простих операцій посування курсора, зокрема команд руху
+словами й реченнями:
+
+ C-f (Forward — уперед.) Перейти на символ уперед
+ C-b (Backward — назад.) Перейти на символ назад
+
+ M-f Перейти на слово вперед
+ M-b Перейти на слово назад
+
+ C-n (Next — наступний.) До наступного рядка
+ C-p (Previous — попередній.) До попереднього рядка
+
+ C-a (Alpha — початок.) Перейти на початок рядка
+ C-e (End — кінець.) Перейти в кінець рядка
+
+ M-a Перейти назад на початок речення
+ M-e Перейти вперед у кінець речення
+
+»» Випробуйте всі ці команди по кілька разів для практики.
+ Ними ви користуватиметесь частіше за всі інші.
+
+Дві інші важливі команди руху курсора — це M-< (META-менше), яка веде
+на початок усього тексту, й M-> (META-більше), яка веде в кінець
+усього тексту.
+
+На більшості терміналів знак „<“ — над латинською комою, тобто ви
+затискаєте SHIFT, щоб його набрати. Відповідно M-< означає затиск не
+лише клавіші META, а ще й клавіші SHIFT. Без SHIFT вийде M-кома.
+
+»» Спробуйте М-< зараз, щоб перейти на початок посібника.
+ Тоді кілька разів наберіть C-v, щоб повернутись сюди.
+
+»» Спробуйте М-> зараз, щоб перейти в кінець посібника.
+ Тоді кілька разів наберіть M-v, щоб повернутись сюди.
+
+Можете також рухати курсор клавішами стрілок, якщо ваш термінал має
+такі клавіші. Втім, радимо опанувати C-b, C-f, C-n і C-p з трьох
+причин. По-перше, вони працюють на будь-яких терміналах. По-друге,
+практикуючи використання Emacs, ви невдовзі виявите, що набирати ці
+Control-символи швидше, ніж набирати стрілки (бо вам не доводиться
+зсувати руки з набірного положення). По-третє, щойно ви звикнете до
+використання цих команд із Control-символами, вам стане легко
+опанувати й інші розширені команди посування курсора.
+
+Більшість команд Emacs приймають числовий аргумент; для більшості
+команд він означає кількість повторів. Щоб передати команді кількість
+повторів, набирайте C-u і цифри, перш ніж набрати команду. Якщо маєте
+клавішу META (чи ALT), то маєте й інший, альтернативний шлях увести
+числовий аргумент: наберіть цифри, затиснувши клавішу META. Радимо
+опанувати шлях C-u, бо він працює на будь-яких терміналах. Числовий
+аргумент також називається «префіксним аргументом», бо ви набираєте
+його перед відповідною йому командою.
+
+Наприклад, C-u 8 C-f посуває курсор на вісім символів уперед.
+
+»» Спробуйте використати C-n чи C-p з числовим аргументом, щоб
+ посунути курсор до рядка поруч із цим рядком єдиною командою.
+
+Числовий аргумент означає для більшості команд кількість повторів, але
+деякі команди використовують його інакше. Декілька команд (але не ті,
+які вам уже відомі) використовують його як прапор: коли передаєте їм
+префіксний аргумент, це незалежно від значення змушує команду робити
+щось нетипове.
+
+C-v та M-v також є винятком. За наявності аргументу вони гортають
+текст угору чи вниз на означену ним кількість рядків, а не на цілий
+екран. Наприклад, C-u 8 C-v прокручує 8 рядків.
+
+»» Спробуйте набрати C-u 8 C-v прямо зараз.
+
+Це мало прогорнути текст на 8 рядків угору. Якщо бажаєте прогорнути
+його знов донизу, передайте аргумент команді M-v.
+
+Якщо ви користуєтесь графічним середовищем, наприклад X чи MS-Windows,
+то з одного боку вікна Emacs має бути висока прямокутна область, яка
+називається панеллю гортання. Можете гортати текст, натискаючи панель
+гортання кнопкою миші.
+
+Якщо у вашої миші є колесо гортання, можете гортати й ним.
+
+
+* ЯКЩО EMACS НЕ ВІДПОВІДАЄ
+--------------------------
+
+Якщо Emacs перестає відповідати на ваші команди, можете дати йому
+копняка, набравши C-g. Використовуйте C-g, щоб припинити команду, яка
+виконується надто довго.
+
+Також використовуйте C-g, щоб відхилити числовий аргумент або початок
+команди, яку передумали дописувати.
+
+»» Наберіть C-u 100, щоб зазначити числовий аргумент «100». Наберіть
+ C-g. Тепер наберіть C-f. Курсор має посунутись лише на один
+ символ, бо ви скасували аргумент набранням C-g.
+
+Ненароком набравши <ESC>, можете позбутись і його за допомогою C-g.
+
+
+* ВИМКНЕНІ КОМАНДИ
+------------------
+
+Деякі команди Emacs усталено «вимкнені», щоб не плутати користувачок і
+користувачів, які лише починають його вивчати.
+
+Коли ви набираєте ту чи іншу вимкнену команду, Emacs показує її назву
+й запитує, чи точно ви бажаєте виконати цю команду.
+
+Якщо ви справді бажаєте спробувати команду, наберіть <SPC> (пробіл) у
+відповідь на запитання. Зазвичай, не бажаючи виконувати вимкнену
+команду, відповідайте на це питання «n».
+
+»» Наберіть C-x C-l (цю команду вимкнено), а тоді наберіть n у
+ відповідь на запитання.
+
+
+* WINDOWS
+---------
+
+Emacs може мати кілька «вікон» — кожне зі своїм текстом. Згодом
+пояснимо, як використовувати декілька вікон одразу. Поки що слід
+розібратись, як позбутись зайвих вікон і повернутись до простого
+редагування в одному вікні. Це просто:
+
+ C-x 1 Одне вікно (тобто припинити всі інші вікна).
+
+Це означає набір CONTROL-x і цифри 1. C-x 1 розширює вікно, яке
+містить курсор, на весь екран, і видаляє всі інші вікна.
+
+»» Посуньте курсор до цього рядка й наберіть C-u 0 C-l. Тоді наберіть
+ C-h k C-f. Це вікно звузиться, й з'явиться нове вікно, в якому
+ буде показано документацію про команду C-f.
+
+»» Наберіть C-x 1 — вікно документації зникне.
+
+Є цілі набори команд, які починаються з CONTROL-x; більшість із них
+стосуються вікон, файлів, буферів тощо. Ці команди містять два, три
+або чотири символи.
+
+
+* ВВЕДЕННЯ Й ВИДАЛЕННЯ
+----------------------
+
+Якщо бажаєте ввести текст, просто наберіть цей текст. Звичайні
+символи, такі як A, 7, * тощо, вводяться прямо при набранні. Аби
+ввести символ нового рядка, натисніть <Return> (ця клавіша на
+клавіатурі часом підписана «Enter»).
+
+Щоб видалити символ перед курсором, наберіть <DEL>. Ця клавіша на
+клавіатурі зазвичай підписана «Backspace» — та сама, якою за межами
+Emacs ви зазвичай видаляєте останній набраний символ.
+
+На клавіатурі зазвичай є ще одна клавіша з підписом <Delete>, але в
+Emacs ми позначаємо <DEL> не її.
+
+»» Прямо зараз наберіть кілька символів, а тоді видаліть їх, набравши
+ <DEL> кілька разів. Сміливо змінюйте цей файл; оригінал посібника
+ залишиться недоторканим. Це ваша особиста одноразова копія.
+
+Коли рядок тексту завеликий для одного рядка на екрані, цей рядок
+тексту «продовжується» на ще один екранний рядок. Якщо ви
+користуєтесь графічним середовищем, на кожному боці текстової області
+(на лівому й правому «полях») з'являються маленькі вигнуті стрілки —
+позначки, де було продовжено той чи інший рядок. Якщо ви користуєтесь
+текстовим терміналом, продовжений рядок позначається оберненою скісною
+рискою («\») в крайній правій колонці екрана.
+
+»» Вводьте текст, доки не сягнете правого поля, а тоді вводьте ще.
+ Побачите, як з'явиться рядок продовження.
+
+»» Натискайте <DEL> раз за разом, щоб видаляти символи, доки рядок
+ тексту не вміститься знову в один екранний рядок. Рядок
+ продовження зникне.
+
+Символ нового рядка можете видалити так само, як будь-який інший.
+Видалення символу нового рядка між двома рядками зливає їх в один
+рядок. Якщо в результаті сполучений рядок ширший, ніж екран, то його
+буде показано з рядком продовження.
+
+»» Посуньте курсор на початок рядка й наберіть <DEL>. Це
+ зіллє той рядок із попереднім.
+
+»» Наберіть <Return>, щоб відновити символ нового рядка на місці щойно
+ видаленого.
+
+Клавіша <Return> особлива тим, що її натиск може не лише вводити
+символ нового рядка. Залежно від навколишнього тексту, її натиск може
+ввести пробіли після символу нового рядка таким чином, щоб текст у
+новоствореному рядку одразу вирівнювався відносно тексту попереднього
+рядка. Ми називаємо цю поведінку (складнішу дію клавіші, ніж просто
+введення відповідного символу) «електричною».
+
+»» Щоб побачити електричну поведінку <Return>,
+ наберіть <Return> у кінці цього рядка.
+
+Простежте, як при введенні символу нового рядка Emacs вводить пробіли
+таким чином, що курсор опиняється під «н» слова «наберіть».
+
+Пам'ятайте, більшості команд Emacs можливо передати кількість
+повторень; це стосується й текстових символів. Повторення текстового
+символу вводить цей символ декілька разів.
+
+»» Спробуйте зараз набрати C-u 8 *, аби ввести ********.
+
+Ви опанували основний спосіб набрати щось в Emacs і виправити помилки.
+Також можна видаляти цілі слова й рядки. Ось підсумок операцій
+видалення:
+
+ <DEL> Видалити символ перед курсором
+ C-d (Delete — видалити.) Видалити символ після курсора
+
+ M-<DEL> Вирізати слово перед курсором
+ M-d Вирізати слово після курсора
+
+ C-k (Kill — вирізати.) Вирізати з рядка все після курсора
+ M-k Вирізати з речення все після курсора
+
+Зважте на те, як <DEL> і C-d продовжують щодо M-<DEL> і M-d паралелі,
+розпочаті C-f і M-f (технічно <DEL> не є керівним символом, але зараз
+це несуттєво). C-k та M-k подібні до C-e та M-e тим, як вони працюють
+із рядками й реченнями відповідно.
+
+Є також спосіб вирізати одразу багато тексту. Перейдіть на початок чи
+в кінець потрібної частини тексту й натисніть C-<SPC>. (<SPC> —
+пробіл.) Тоді посуньте курсор на інший край частини тексту, яку
+бажаєте вирізати. Коли ви це робитимете, Emacs підсвітить текст між
+курсором і тим місцем, де ви набрали C-<SPC>. Нарешті наберіть C-w
+(whole — повністю). Це повністю виріже позначений текст.
+
+»» Посуньте курсор до «Є» на початку попереднього абзацу.
+»» Введіть C-<SPC>. Emacs має показати повідомлення «Mark set»
+ («Позначку встановлено») внизу екрана.
+»» Посуньте курсор до «п» в слові «потрібної» другого рядка абзацу.
+»» Наберіть C-w. Це виріже текст від «Є» включно до «п» не включно.
+ Якби ви набрали M-w, це його лише скопіювало б.
+
+Вирізання й видалення відрізняються тим, що вирізаний текст можливо
+вставити (будь-куди), тоді як видалене вставити неможливо (втім,
+можливо скасувати видалення — про це згодом). Вставка, так би мовити,
+виймає (yank) раніше вилучений текст. Зазвичай усі команди, які
+вилучають багато тексту, вирізають його (їх налаштовано таким чином,
+щоб ви могли потім вставити цей текст); а от команди, які вилучають
+лише один символ або порожні рядки чи пробіли, просто їх видаляють
+(без можливості вставлення). <DEL> і C-d без аргументу здійснюють
+видалення. За наявності аргументу вони вирізають.
+
+»» Посуньте курсор на початок рядка, в якому є символи.
+ Тоді наберіть C-k, щоб вирізати текст у цьому рядку.
+»» Наберіть C-k іще раз. Це виріже той символ нового рядка,
+ що завершує цей рядок.
+
+Зауважте, перший C-k вирізає вміст рядка, а другий C-k вирізає сам
+рядок і зсуває догори всі наступні рядки. C-k із числовим аргументом
+працює інакше: вирізає водночас вміст і самі рядки. Це не просто
+повторення. C-u 2 C-k вирізає два рядки разом із їхніми символами
+нового рядка; набравши C-k двічі, ви отримаєте інший результат.
+
+Можете вставити вирізаний текст туди ж, звідки його вирізали, або до
+певного іншого місця в редагованому тексті — навіть в інший файл.
+Можете вставляти один і той самий текст кілька разів; це створить
+кілька його копій. Англійською вирізання називають «kill» або «cut»,
+виймання (вставку) — «yank» або «paste»; перегляньте згодом глосарій у
+підручнику Emacs.
+
+Команда C-y вставляє останній вирізаний текст туди, де зараз курсор.
+
+»» Спробуйте набрати C-y, щоб вставити текст назад.
+
+Якщо наберете C-k декілька разів поспіль, увесь вирізаний текст
+збережеться разом, щоб одною командою C-y ви могли вставити водночас
+усі рядки.
+
+»» Спробуйте зараз набрати C-k декілька разів.
+
+Тепер отримаймо вирізаний текст:
+
+»» Наберіть C-y. Посуньте курсор на кілька рядків униз і наберіть C-y
+ знову. Тепер ви знаєте, як копіювати текст.
+
+Що робити, коли вже вирізали певний текст для вставки, але після цього
+вирізали ще щось? C-y вставляє найновіше вирізане. Проте минулого
+вирізаного не втрачено. Можете повернутись до нього командою M-y.
+Набравши C-y та вийнявши цим найновіше вирізане, наберіть M-y іще раз,
+щоб замінити вставлений текст на попереднє вирізане. Набирайте M-y
+знову й знову, щоб виймати минулі вирізання. Досягнувши шуканого
+тексту, ви не маєте більше нічого робити, щоб його зафіксувати.
+Просто продовжуйте редагувати, залишивши вставлений текст на місці.
+
+Набравши M-y достатньо разів, виймете найновіше вирізане знову.
+
+»» Виріжте рядок, посуньте курсор і виріжте ще один рядок.
+
+»» Тоді наберіть C-y, щоб отримати другий вирізаний рядок. Тоді
+ наберіть M-y, і той рядок заміниться на перший вирізаний рядок.
+
+»» Наберіть M-y іще кілька разів і простежте, що вийматиметься.
+ Продовжуйте набирати M-y, доки не виймете знову другий вирізаний
+ рядок, і тоді наберіть ще декілька M-y. За бажання спробуйте
+ передати M-y додатні чи від'ємні аргументи.
+
+
+* СКАСУВАННЯ
+------------
+
+Помилково змінивши текст, можете скасувати цю зміну командою
+скасування C-_, тобто затисніть Control та Shift і натисніть дефіс.
+
+Зазвичай C-_ скасовує зміни, внесені одною командою; якщо ви наберете
+кілька C-_ поспіль, кожне повторення скасує ще по одній команді.
+
+Але є два винятки. Команди, які не змінюють тексту, не враховуються
+(зокрема це команди руху курсора й команди гортання). Й текстові
+символи зазвичай обробляються по 20 водночас. (Це щоб зменшити
+кількість C-_, потрібних для скасування вставки тексту.)
+
+»» Виріжте цей рядок за допомогою C-k. Тоді наберіть C-_, щоб він
+ з'явився знову.
+
+C-/ — альтернативна команда скасування; вона працює так само, як C-_.
+Деякі термінали дають змогу набирати C-_ без клавіші Shift. Деякі
+термінали насправді передають Emacs саме C-_, коли ви набираєте C-/.
+Ще є команда C-x u, котра працює так само, як C-_, але менш зручна для
+набрання. Посібники для латинських розкладок описують команду C-/ як
+основну, проте українською C-_ набирати легше.
+
+Числовий аргумент для C-_, C-/ чи C-x u працює як кількість повторень.
+
+Можете скасувати видалення тексту так само, як скасовуєте вирізання.
+Відмінність між вирізанням і видаленням полягає в тому, чи можете ви
+вставити текст за допомогою C-y; для скасування нема жодної різниці.
+
+
+* ФАЙЛИ
+-------
+
+Щоб зробити зміни до тексту постійними, їх треба зберегти до файлу.
+Інакше ці зміни зникнуть при виході з Emacs. Аби зберегти текст до
+файлу, вам потрібно «знайти» файл, перш ніж ввести текст. (Це також
+називають «відкриттям» файлу.)
+
+Знаходження файлу показує його вміст усередині Emacs. Це виглядає,
+ніби ви редагуєте файл безпосередньо. Проте зміни, які ви вносите за
+допомогою Emacs, не стають постійними, доки ви не «збережете» файл.
+Це щоб не залишати лише частково зміненого файлу в системі, коли ви
+цього не бажаєте. Навіть після збереження Emacs залишає початковий
+файл під іншою назвою, щоб ви змогли згодом скасувати зміни, якщо вони
+виявляться помилковими.
+
+Якщо ви роздивитесь низ екрану, то помітите рядок, який містить дефіси
+й починається з чогось на кшталт « -:--- TUTORIAL». Ця частина екрану
+зазвичай показує назву файлу, який ви редагуєте. Зараз ви
+переглядаєте свою особисту копію посібника Emacs, названу «TUTORIAL».
+Коли ви знаходите файл за допомогою Emacs, назва цього файлу
+показується саме в тому місці.
+
+Команда знаходження файлу особлива тим, що запитує вас, який файл вам
+треба. Іншими словами, команда «зчитує аргумент» (у цьому випадку
+аргумент — назва файлу). Після набрання команди:
+
+ C-x C-f (Find — знайти.) Знайти файл
+
+Emacs попрохає вас набрати назву файлу. При введенні назву файлу
+показано в нижньому рядку екрана. Нижній рядок називають мінібуфером,
+коли він використовується для таких запитів. Можете використовувати
+звичні команди редагування Emacs, щоб редагувати назву файлу.
+
+Коли ви вводите назву файлу (чи заповнюєте інший мінібуфер), можете
+скасувати команду за допомогою C-g.
+
+»» Наберіть C-x C-f, а тоді наберіть C-g. Це скасує мінібуфер, а
+ також команду C-x C-f, яка використовувала мінібуфер. Тому ви не
+ знайдете жодного файлу.
+
+Коли ви введете назву файлу до кінця, наберіть <Return>, щоб завершити
+введення. Мінібуфер зникне, й команда C-x C-f спробує знайти обраний
+вами файл.
+
+Вміст файлу з'явиться на екрані, й ви зможете редагувати цей вміст.
+Коли вирішите зберегти зміни на постійно, наберіть команду:
+
+ C-x C-s (Save — зберегти.) Зберегти
+
+Це скопіює текст із Emacs до файлу. Коли ви робите це вперше, Emacs
+перейменовує початковий файл, щоб його не було втрачено. Нова назва
+формується доданням «~» у кінець назви початкового файлу. Завершивши
+збереження, Emacs показує назву записаного файлу.
+
+»» Наберіть C-x C-s TUTORIAL <Return>.
+ Це має зберегти посібник у файл із назвою «TUTORIAL» і показати
+ «Wrote ...TUTORIAL» унизу екрана.
+
+Можете знайти вже наявний файл, щоб переглянути чи відредагувати його.
+Або можете «знайти» файл, якого ще не існує. Так в Emacs створюють
+файли: відкривають порожній файл і починають вводити текст у цей файл.
+Коли ви попросите «зберегти» файл, Emacs насправді створить файл зі
+введеним вами текстом. Відтоді можете вважати, що редагуєте вже
+наявний файл.
+
+
+* БУФЕРИ
+--------
+
+Коли знаходите ще один файл за допомогою C-x C-f, перший файл
+залишається в Emacs. Можете перемкнутись на нього, знайшовши його
+знову за допомогою C-x C-f. Таким чином в Emacs можливо відкрити
+чимало файлів.
+
+Emacs зберігає текст кожного файлу всередині об'єкта — так званого
+«буфера». Знаходження файлу створює буфер усередині Emacs. Щоб
+переглянути перелік уже наявних буферів, наберіть
+
+ C-x C-b (Buffer — буфер.) Перелічити буфери
+
+»» Спробуйте C-x C-b прямо зараз.
+
+Зауважте, що кожен буфер має власну назву, а ще біля нього може бути
+назва того файлу, вміст якого він утримує. Будь-який текст, який ви
+бачите у вікні Emacs, завжди є частиною певного буфера.
+
+»» Наберіть C-x 1, щоб позбутись переліку буферів.
+
+Коли буферів декілька, лише один із них може бути «поточним». Це той
+буфер, який ви редагуєте. Якщо бажаєте редагувати інший буфер, на
+нього слід «перемкнутись». Якщо бажаєте перемкнутись на буфер, що
+відповідає певному файлу, відкрийте файл знову за допомогою C-x C-f.
+Але простіше використати команду C-x b. Цій команді достатньо
+передати назву буфера.
+
+»» Відкрийте файл «foo», набравши C-x C-f foo <Return>. Тоді наберіть
+ C-x b TUTORIAL <Return>, щоб повернутись до цього посібника.
+
+Зазвичай назва буфера збігається з назвою файлу (без шляху). Втім, це
+не завжди так. Перелік буферів, відкритий за допомогою C-x C-b,
+показує як назву буфера, так і назву файлу кожного буфера.
+
+Деякі буфери не відповідають файлам. Буфер *Buffer List* («Перелік
+буферів»), який показує створені за допомогою C-x C-b буфери, не має
+жодного файлу. Цей буфер TUTORIAL спершу не мав файлу, але тепер має,
+бо в попередньому розділі ви набрали C-x C-s і зберегли його до файлу.
+
+Буфер *Messages* також не відповідає жодному файлу. Цей буфер містить
+повідомлення, які з'являлись у нижньому рядку вашого сеансу Emacs.
+
+»» Наберіть C-x b *Messages* <Return>, щоб переглянути буфер
+ повідомлень. Тоді наберіть C-x b TUTORIAL <Return>, щоб
+ повернутись до цього посібника.
+
+Якщо змінити текст одного файлу й знайти інший файл, то перший файл не
+буде збережено. Зміни залишаться всередині Emacs у буфері цього
+файлу. Створення чи редагування буфера другого файлу не впливає на
+буфер першого файлу. Це дуже корисно, але буфер першого файлу теж
+треба якось зберігати. Перемикатись на цей буфер, щоб зберегти його
+за допомогою C-x C-s, було б незручно. Тож маємо
+
+ C-x s (Save — зберегти.)
+ Зберегти певні буфери до їхніх файлів
+
+C-x s запитує вас про кожен буфер, який ви змінили й не зберегли, чи
+бажаєте ви його зберегти.
+
+»» Введіть рядок тексту й наберіть C-x s.
+ Маєте отримати запитання, чи бажаєте ви зберегти буфер TUTORIAL.
+ Погодьтесь, набравши у відповідь «y».
+
+
+* РОЗШИРЕННЯ НАБОРУ КОМАНД
+--------------------------
+
+Команд Emacs значно більше, ніж можливо розкласти по всіх Control- і
+Meta-символах. Emacs обходить це за допомогою команди x (extend —
+розширити). Вона має два різновиди:
+
+ C-x Запитує один символ.
+ M-x Запитує англійську назву команди.
+
+Ці команди дуже корисні, проте використовуються менш часто, ніж ті
+команди, які ви вже опанували. Деякі з цих команд ви вже бачили,
+наприклад файлові команди C-x C-f для знаходження й C-x C-s для
+збереження. Ще один приклад — команда завершення сеансу Emacs: C-x
+C-c пропонує зберегти кожен змінений файл, перш ніж зупинити Emacs.
+
+Якщо ви користуєтесь графічним середовищем, вам не потрібні жодні
+додаткові команди для переходу від Emacs до іншого застосунку. Можете
+переходити мишею чи командами менеджера вікон. Але якщо ви
+користуєтесь текстовим терміналом, який може показувати лише один
+повноекранний застосунок, то вам потрібно «призупинити» Emacs, щоб
+перейти до іншого застосунку.
+
+Команда C-z виходить з Emacs *тимчасово* — тобто ви можете повернутись
+до цього ж сеансу Emacs згодом. Коли Emacs запущено в текстовому
+терміналі, C-z «призупиняє» Emacs, тобто повертає вас до оболонки, але
+не припиняє завдання Emacs. У найпоширеніших оболонках ви можете
+відновити Emacs командою «fg» або «%emacs».
+
+Використовувати C-x C-c слід перед виходом із системи. Ще цією
+командою слід закривати той Emacs, який ви запустили для швидкого
+редагування, наприклад за допомогою знаряддя обробки пошти.
+
+Команд C-x чимало. Ось перелік тих, які ви вже опанували:
+
+ C-x C-f (Find — знайти.) Знайти файл.
+ C-x C-s (Save — зберегти.) Зберегти буфер до файлу.
+ C-x s Зберегти певні буфери до їхніх файлів.
+ C-x C-b (Buffer — буфер.) Перелічити буфери.
+ C-x b Перемкнути буфер.
+ C-x C-c (Close — закрити.) Вийти з Emacs.
+ C-x 1 Видалити всі вікна, крім одного.
+ C-x u (Undo — скасувати.) Скасувати останню дію.
+
+Розширені команди, які використовуються менш часто чи лише в певних
+режимах, мають довші англійські назви. Наприклад, команда
+replace-string («замінити рядок») змінює в буфері один рядок на інший.
+Коли ви набираєте M-x, Emacs показує внизу екрана запит M-x, у
+відповідь на який вам слід набрати назву команди — «replace-string» у
+цьому випадку. Просто наберіть «repl s<TAB>» — і Emacs допише назву
+команди. (<TAB> — це клавіша Tab, яку зазвичай розміщено над клавішею
+Caps Lock чи Shift ліворуч на клавіатурі.) Підтвердьте назву команди
+клавішею <Return>.
+
+Команда replace-string потребує двох аргументів: рядка, який слід
+замінити, й рядка, яким ви його замінюєте. Введення кожного аргументу
+потрібно завершити клавішею <Return>.
+
+»» Посуньте курсор до порожнього рядка двома рядки нижче, ніж цей.
+ Тоді наберіть M-x repl s<Return>змінено<Return>перетворено<Return>.
+
+ Зверніть увагу на те, як зміниться цей рядок: ви заміните слово
+ «змінено» на слово «перетворено» в усіх місцях після курсора, де
+ воно зустрічається.
+
+
+* САМОЗБЕРЕЖЕННЯ
+----------------
+
+Коли ви змінюєте файл, але не зберігаєте змін, то ці зміни може бути
+втрачено, якщо комп'ютер зазнає збою. Emacs захищає вас від цього
+періодичним записом файлів «самозбереження» для кожного редагованого
+файлу. Назва файлу самозбереження починається й закінчується символом
+#, тобто якщо ваш файл називається «hello.c», його файл самозбереження
+називатиметься «#hello.c#». Коли ви зберігаєте файл звичним шляхом,
+Emacs видаляє відповідний файл самозбереження.
+
+Після збою комп'ютера ви можете відновити самозбережені правки,
+знайшовши файл як зазвичай (редагований файл, не файл самозбереження)
+й набравши M-x recover-this-file <Return>. (Команда перекладається як
+«відновити цей файл».) У відповідь на запит підтвердження, наберіть
+yes<Return>, щоб погодитись і відновити дані самозбереження.
+
+
+* ВІДЛУННЯ
+----------
+
+Коли Emacs помічає, що ви поволі набираєте багатосимвольну команду,
+він показує вам набрану частину команди внизу екрана в області, яку
+називають echo — відлунням. Ця область покриває нижній рядок екрана.
+
+
+* РЯДОК РЕЖИМУ
+--------------
+
+Рядок прямо над областю відлуння називають «рядком режиму». В рядку
+режиму має виводитись щось таке:
+
+ -:**- TUTORIAL 63% L749 (Fundamental)
+
+Цей рядок надає корисні дані про стан Emacs і редагованого тексту.
+
+Ви вже знаєте, що значить TUTORIAL: це назва того файлу, який ви
+знайшли раніше. ЧЧ% повідомляє, в якій частині буфера тексту ви
+перебуваєте; це означає, що ЧЧ відсотків буфера зараз над екраном.
+Якщо верх буфера видно на екрані, то замість «0%» буде «Top» — «Верх».
+Якщо низ буфера видно на екрані, то буде показано «Bot» — «Низ».
+Якщо ви читаєте такий маленький буфер, що весь його вміст видно на
+одному екрані, то в рядку режиму буде «All» — «Усе».
+
+Літера L (line — рядок) і цифри показують інший аспект вашого
+місцеперебування — номер рядка поточної точки.
+
+Зірки спереду вказують, що ви змінили текст. Коли файл тільки
+відкрито чи збережено, ця частина рядка режиму показує лише дефіси,
+без зірок.
+
+Частина рядка режиму всередині дужок вказує, які режими редагування
+наразі чинні. Типовий режим — це Fundamental («основний»); саме ним
+ви зараз користуєтесь. Це один із «вищих» режимів.
+
+Emacs має чимало різних вищих режимів. Деякі з них призначені для
+редагування різних мов і/або видів тексту, зокрема режим Lisp (для
+мови програмування Лісп), режим Text (для тексту) тощо. В певну мить
+активним може бути один і тільки один вищий режим, і його назву завжди
+можна знайти в рядку режиму — там, де зараз ви бачите Fundamental.
+
+Кожен вищий режим змінює поведінку декількох команд. Наприклад, є
+команди для створення коментарів у програмі, й оскільки кожна мова
+програмування по-своєму визначає вигляд коментарів, то й кожен вищий
+режим має вставляти коментарі по-своєму. Кожен вищий режим є назвою
+тої команди розширення, якою ви його вмикаєте. Наприклад, командою
+M-x fundamental-mode ви вмикаєте основний режим.
+
+Для редагування тексту мовами людського спілкування, такими як цей
+файл, ви зазвичай використовуватимете режим Text.
+
+»» Наберіть M-x text-mode <Return>.
+
+Не переймайтесь, жодні з уже відомих вам команд Emacs не стануть
+поводитись геть інакше. Проте ви можете помітити, що M-f і M-b тепер
+обробляють апострофи як частини слів. Досі, в режимі Fundamental, M-f
+і M-b обробляли апострофи як пунктуацію.
+
+Вищі режими зазвичай вносять саме такі невеличкі зміни: більшість
+команд продовжують виконувати звичні завдання — з деякими
+відмінностями в деталях.
+
+Щоб переглянути документацію про поточний вищий режим, наберіть C-h m.
+
+»» Посуньте курсор до рядка, наступного після цього.
+»» Наберіть C-l C-l, щоб посунути цей рядок угору екрана.
+»» Наберіть C-h m, щоб побачити різницю режимів Text і Fundamental.
+»» Наберіть C-x 1, щоб вилучити документацію з екрана.
+
+Вищі режими називаються вищими, тому що бувають і нижчі режими. Нижчі
+режими не заміщають вищих режимів, а трошки їх змінюють. Кожен нижчий
+режим можна ввімкнути чи вимкнути окремо, незалежно від усіх інших
+нижчих режимів — і незалежно від вашого вищого режиму. Тож ви можете
+не використовувати нижчих режимів зовсім, або використовувати єдиний
+нижчий режим, або поєднувати декілька нижчих режимів.
+
+Один із дуже корисних нижчих режимів, особливо для редагування тексту
+мовами людського спілкування, — це режим Auto Fill (самозаповнення).
+Коли цей режим увімкнено, Emacs автоматично вставляє символ нового
+рядка між словами, коли при введенні тексту певний рядок виявляється
+занадто широким.
+
+Режим самозаповнення вмикається командою M-x auto-fill-mode <Return>.
+Коли режим увімкнено, можете вимкнути його знову тою ж командою. Якщо
+режим вимкнено, команда його вмикає; а коли режим увімкнено, команда
+його вимикає. Можна сказати, що команда «перемикає режим».
+
+»» Наберіть M-x auto-fill-mode <Return>. Тоді набирайте «йцук » знов
+ і знов, доки рядок не поділиться на два. Пробіли слід набирати,
+ оскільки самозаповнення розбиває рядки тільки на пробілах.
+
+Поле зазвичай починається після 70 символів, але можете змінити це
+командою C-x f. Передайте бажане значення поля числовим аргументом
+цій команді.
+
+»» Наберіть C-x f із аргументом 20. (C-u 2 0 C-x f).
+ Тоді наберіть будь-який текст і зверніть увагу, яким чином Emacs
+ поділить його на 20-символьні рядки. Тоді поверніть полю значення
+ 70 за допомогою ще одної команди C-x f.
+
+Якщо ви зміните щось посеред абзацу, режим самозаповнення не ділитиме
+абзацу на рядки заново без вашого дозволу.
+Щоб поділити абзац заново (замінюючи наявні символи нового рядка),
+посуньте курсор до цього абзацу й наберіть M-q (META-q).
+
+»» Посуньте курсор до попереднього абзацу й наберіть M-q.
+
+
+* ПОШУК
+-------
+
+Emacs уміє шукати рядки (групи послідовних символів) в тексті як після
+курсора, так і перед ним. Пошук рядка є командою руху курсора, тобто
+посуває курсор до наступного місця, де з'являється цей рядок.
+
+Команда пошуку Emacs є покроковою. Тобто пошук відбувається прямо при
+набранні рядка, який ви бажаєте шукати.
+
+Пошук уперед розпочинає команда C-s (search — пошук), а пошук назад —
+команда C-r (reverse — навпаки). АЛЕ ЗАЧЕКАЙТЕ! Не поспішайте
+випробовувати ці команди.
+
+Набравши C-s, ви помітите, що область відлуння покаже рядок
+«I-search». Це означатиме, що Emacs перейшов до режиму incremental
+search — покрокового пошуку — й очікує, поки ви наберете, що бажаєте
+шукати. <Return> завершує пошук.
+
+»» Тепер наберіть C-s, щоб розпочати пошук. ПОВОЛІ, літера за
+ літерою, наберіть слово «курсор», зупиняючись після кожного символу
+ й звертаючи увагу на те, що відбувається з курсором. Отже, ви
+ щойно пошукали «курсор» один раз.
+»» Наберіть C-s іще раз — знайдіть наступну послідовність «курсор».
+»» Тепер наберіть <DEL> чотири рази й зауважте, куди зсунеться курсор.
+»» Наберіть <Return>, щоб завершити пошук.
+
+Щойно ви спостерігали, як покроковий пошук Emacs намагається перейти
+до послідовності, збіжної з набраним вами рядком. Щоб перейти до
+наступної послідовності «курсор», наберіть C-s іще раз. Якщо такої
+послідовності не існує, Emacs сигналить і повідомляє, що пошук наразі
+«failing» — неуспішний. C-g завершує пошук у будь-якому разі.
+
+Якщо під час покрокового пошуку набрати <DEL», пошук «повертається» до
+попередньої точки. Якщо набрати <DEL> одразу після C-s — переходу до
+наступного збігу з шуканим рядком — то <DEL> поверне курсор до
+попереднього збігу. Якщо збігів перед курсором нема, <DEL> зітре
+останній символ рядка пошуку. Наприклад, наберіть «к», щоб пошукати
+перший збіг із «к». Тоді наберіть «у» — це посуне курсор до першого
+збігу з «ку». Нарешті наберіть <DEL> — це зітре «у» з рядка пошуку,
+тож курсор повернеться до першого збігу з «к».
+
+Якщо посеред пошуку ви набираєте Control- чи Meta-символ (за винятком
+символів власне пошуку, як-от C-s чи C-r), пошук припиняється.
+
+C-s розпочинає пошук будь-якого збігу з шуканим рядком ПІСЛЯ того
+місця, де курсор зараз. Якщо бажаєте пошукати щось у більш ранньому
+тексті, наберіть натомість C-r. Усе, що ми зазначили про C-s,
+стосується й C-r, — крім напряму пошуку, який стає зворотним.
+
+
+* ДЕКІЛЬКА ВІКОН
+----------------
+
+Emacs має ту файну властивість, що ви можете переглядати водночас
+декілька вікон на одному екрані. (Зауважте, що Emacs використовує
+роз'яснений у наступному розділі термін «рамка», або frame, замість
+вжитого в деяких інших застосунках терміна «вікно».) Підручник Emacs
+містить глосарій термінів Emacs.
+
+»» Посуньте курсор до цього рядка й наберіть C-l C-l.
+
+»» Наберіть C-x 2 — розділіть екран на два вікна. Обидва вікна
+ показуватимуть цей посібник. Курсор редагування залишатиметься в
+ горішньому вікні.
+
+»» Наберіть C-M-v — перегорніть нижнє вікно.
+ (Якщо не маєте клавіші META, наберіть <ESC> C-v.)
+
+»» Наберіть C-x o (other — інше), щоб посунути курсор до нижнього
+ вікна. Погортайте нижнє вікно за допомогою C-v та M-v. Читайте ці
+ вказівки далі в горішньому вікні.
+
+»» Наберіть C-x o ще раз, щоб посунути курсор назад до горішнього
+ вікна. Курсор у горішньому вікні опиниться там же, де був досі.
+
+Можете й надалі перемикатись між вікнами за допомогою C-x o. «Обране»
+вікно, в якому переважно відбувається редагування, — це те вікно, в
+якому ви бачите помітний курсор, який блимає, коли ви нічого не
+набираєте. Кожне вікно має власну точку, на яку вказує його курсор;
+якщо ви запускаєте Emacs у графічному середовищі, ці курсори не
+блимають і мають вигляд порожніх коробок.
+
+Команда C-M-v дуже корисна, коли ви редагуєте текст в одному вікні й
+використовуєте інше вікно лише як довідку. Не виходячи з обраного
+вікна, ви можете гортати текст в іншому вікні за допомогою C-M-v.
+
+C-M-v — це один із CONTROL-META-символів. Якщо ви маєте клавішу META
+(чи Alt), то можете набрати C-M-v, затиснувши водночас клавіші CONTROL
+та META й натиснувши v. Неважливо, яку з клавіш CONTROL і META ви
+затиснете першою, бо ці клавіші не діють самостійно, а змінюють
+символи, які ви набираєте.
+
+Якщо у вас нема клавіші META, можете використати натомість <ESC>, але
+тоді порядок таки важливий: наберіть спершу <ESC>, а тоді CONTROL-v.
+CONTROL-<ESC> v не спрацює, бо <ESC> не змінює інші символи, а є
+повноцінною клавішею.
+
+»» Наберіть C-x 1 (у горішньому вікні), щоб позбутись нижнього вікна.
+
+(Якби ви набрали C-x 1 у нижньому вікні, то позбулися б горішнього
+вікна. Уявляйте цю команду як «Залишити лише одне вікно — те, в якому
+я зараз».)
+
+Показувати один і той самий буфер в обох вікнах необов'язково. Якщо в
+одному вікні ви наберете C-x C-f і знайдете файл, то на інше вікно це
+не вплине. Можете знаходити файли в обох вікнах незалежно.
+
+Ось ще один шлях застосування двох вікон для показу двох різних речей:
+
+»» Наберіть C-x 4 C-f та назву одного зі своїх файлів. Завершіть за
+ допомогою <Return>. Зазначений файл з'явиться в нижньому вікні.
+ Курсор також туди посунеться.
+
+»» Наберіть C-x o, щоб перейти до горішнього вікна,
+ й C-x 1, щоб видалити нижнє вікно.
+
+
+* ДЕКІЛЬКА РАМОК
+----------------
+
+Emacs також дає змогу створити декілька «рамок» (frames). Рамкою
+називають будь-яку добірку вікон разом із її меню, панелями гортання,
+областю відлуння тощо. У графічних середовищах Emacs називає рамкою
+те, що багато інших застосунків називають «вікном». Екран може
+показувати декілька графічних рамок водночас. На текстовому терміналі
+може бути видно лише одну рамку.
+
+»» Наберіть C-x 5 2.
+ На вашому екрані з'явиться нова рамка.
+
+У новій рамці ви можете робити все те, що й у початковій рамці.
+Початкова рамка не є чимось особливим.
+
+»» Наберіть C-x 5 0.
+ Це вилучить обрану рамку.
+
+Вилучити рамку можна й тим звичним шляхом, який передбачає графічне
+середовище (зазвичай це кнопка «X» в одному з горішніх кутів рамки).
+Якщо вилучити таким чином останню рамку сеансу Emacs, увесь Emacs буде
+припинено.
+
+
+* РІВНІ РЕКУРСІЇ РЕДАГУВАННЯ
+----------------------------
+
+Інколи ви потраплятимете в так званий «рівень рекурсії редагування».
+Його позначають квадратні дужки в рядку режиму навколо круглих дужок
+назви вищого режиму. Наприклад, ви можете бачити [(Fundamental)]
+замість (Fundamental).
+
+Щоб вийти з рівня рекурсії редагування, наберіть <ESC> <ESC> <ESC>.
+Це всеохопна команда виходу. Можете використовувати її й для закриття
+зайвих вікон чи виходу з мінібуфера.
+
+»» Наберіть M-x, щоб потрапити до мінібуфера.
+ Тоді наберіть <ESC> <ESC> <ESC>, щоб із нього вийти.
+
+Вийти з рівня рекурсії редагування за допомогою C-g неможливо, бо C-g
+використовується для скасування команд і аргументів УСЕРЕДИНІ рівня
+рекурсії редагування.
+
+
+* ОТРИМАТИ БІЛЬШЕ ДОВІДКИ
+-------------------------
+
+Цей посібник намагається надати необхідний для початку роботи з Emacs
+мінімум даних. Emacs уміє стільки всього, що одним посібником описати
+всі його функції було б неможливо. Проте вам буде цікаво дізнатись
+більше про Emacs та його корисні функції. Emacs надає команди для
+читання документації про команди Emacs. Усі команди довідки (help)
+починаються з CONTROL-h — символу довідки.
+
+Для отримання довідки наберіть символ C-h, а тоді той символ, довідку
+якого бажаєте прочитати. Якщо ви СПРАВДІ загубились, C-h ? попрохає
+Emacs перелічити розділи довідки. Якщо ви набрали C-h і передумали
+читати довідку, натисніть C-g для скасування.
+
+(Якщо C-h не показує довідкового повідомлення внизу екрана, спробуйте
+набрати клавішу F1 чи M-x help <Return> натомість.)
+
+Основна функція довідки — це C-h c. Наберіть C-h, символ c, а також
+символ чи послідовність команди; тоді Emacs покаже коротенький
+англійський опис цієї команди.
+
+»» Наберіть C-h c C-p.
+
+Має з'явитись повідомлення на кшталт:
+
+ C-p runs the command previous-line
+
+Тобто «C-p виконує команду previous-line (попередній рядок)». Це
+повідомляє вам назву функції. Оскільки назви функцій добираються
+таким чином, щоб зображати дії, виконувані відповідною командою,
+вони можуть слугувати коротенькою документацією — достатньою, щоб
+нагадати вам команди, які ви вже опанували.
+
+Багатосимвольні команди, такі як C-x C-s чи <ESC>v (замість M-v, якщо
+не маєте клавіш META й ALT), також можна зазначати після C-h c.
+
+Щоб дізнатися більше про команду, зокрема про клавіші, які можна
+набирати після неї, використайте C-h k (keys — клавіші) замість C-h c
+(command — команда).
+
+»» Наберіть C-h k C-p.
+
+Це покаже у вікні Emacs документацію функції та її назву. Дочитавши
+показане, наберіть C-x 1, щоб позбутись того вікна. Робити це одразу
+необов'язково. Можете продовжити редагування, звіряючись із текстом
+довідки, й набрати C-x 1 лише згодом.
+
+Ось кілька інших корисних варіантів C-h:
+
+ C-h x Описати команду. Вам буде треба набрати назву команди.
+
+»» Спробуйте набрати C-h x previous-line <Return>.
+ Це покаже всі наявні в Emacs дані про ту функцію,
+ яка втілює команду C-p.
+
+Схожа команда C-h v показує документацію змінних — зокрема тих,
+значення яких ви можете змінити для налаштування поведінки Emacs.
+Наберіть назву змінної, коли Emacs її у вас запитає.
+
+ C-h a (Apropos — пов'язане.) Наберіть ключове слово — й
+ Emacs покаже всі команди, назви яких містять це слово.
+ Всі ці команди можна викликати за допомогою META-x.
+ Для деяких команд Apropos наводить також символи чи
+ послідовності, які виконують цю ж команду.
+
+»» Наберіть C-h a file <Return>.
+
+Це покаже в ще одному вікні перелік усіх команд M-x, назви яких
+містять «file» — файл. Поруч із назвами команд ви побачите відповідні
+їм символи (як-от C-x C-f поруч із find-file — знайти файл).
+
+»» Наберіть C-M-v, щоб прогорнути вікно довідки.
+ Повторіть це декілька разів.
+
+»» Наберіть C-x 1, щоб видалити вікно довідки.
+
+ C-h i (Info — дані.) Читати вкладені підручники. Ця команда
+ веде вас до особливого буфера *info*, в якому ви можете
+ читати підручники про встановлені у вашій системі пакунки.
+ Наберіть m emacs <Return>, щоб почитати підручник Emacs.
+ Якщо ви досі не користувались Info, наберіть h — і Emacs
+ запустить для вас путівник можливостями режиму Info.
+ Опрацювавши цей посібник, звертайтесь до Info-підручника
+ Emacs як до основної документації.
+
+
+* БІЛЬШЕ ФУНКЦІЙ
+----------------
+
+Щоб дізнатись більше про Emacs, почитайте його підручник усередині
+Emacs, скориставшись меню Help (Довідка) чи набравши C-h r. Дві
+функції, які можуть вас особливо зацікавити, це Completion —
+доповнення, яке заощаджує натиски клавіш; і Dired — редагування
+каталогів, яке спрощує керування файлами.
+
+Доповнення дає змогу набирати менше тексту. Наприклад, щоб
+перемкнутись на буфер *Messages*, можете набрати C-x b *M<Tab> — і
+Emacs заповнить решту назви буфера настільки, наскільки зможе вивести
+з уже набраного вами тексту. Доповнення також працює з назвами команд
+і файлів. Підручник Emacs описує доповнення в розділі «Completion».
+
+Dired дає змогу перелічувати файли в каталозі (а на вимогу ще й у
+підкаталогах), рухатися цим переліком, відкривати, перейменовувати й
+видаляти файли тощо. Підручник Emacs описує керування файлами в
+розділі «Dired».
+
+Підручник також описує безліч інших функцій Emacs.
+
+
+* ВСТАНОВЛЕННЯ ПАКУНКІВ
+-----------------------
+
+Спільнотою Emacs розроблено величезну добірку пакунків, які роблять
+Emacs потужнішим. Ці пакунки містять підтримку нових мов, теми
+оформлення, додатки для взаємодії з іншими застосунками — й ще
+багато-багато всього.
+
+Щоб переглянути перелік усіх доступних пакунків, наберіть M-x
+list-packages. З'явиться екран, за допомогою якого ви можете
+встановлювати й видаляти пакунки, а також читати описи пакунків.
+Підручник Emacs розповідає про керування пакунками докладніше.
+
+
+* ОТОЖ
+------
+
+Щоб вийти з Emacs, наберіть C-x C-c.
+
+Посібник має на меті бути зрозумілим усім новим користувачкам і
+користувачам, тож якщо будь-що роз'яснено нечітко чи помилково —
+скаржтесь! Український переклад: Денис Никула <vegan@libre.net.ua>.
+
+
+* КОПІЮВАННЯ
+------------
+
+Цей посібник — нащадок цілого родоводу посібників Emacs, починаючи з
+первісного посібника Emacs, який написав Стюарт Кракрафт.
+
+Ця версія посібника — складник GNU Emacs. Її захищено авторським
+правом. Розповсюджувати копії дозволено за певних умов:
+
+ Copyright (C) 1985, 1996, 1998, 2001-2022 Free Software Foundation,
+ Inc. (Фонд вільного програмного забезпечення, Inc.)
+
+ Цей файл — складник GNU Emacs.
+
+ GNU Emacs — вільне програмне забезпечення: можете розповсюджувати
+ й/або змінювати його згідно з умовами Загальної громадської ліцензії
+ GNU в тому вигляді, в якому її публікує Фонд вільного програмного
+ забезпечення, — версії 3 чи (на ваш розсуд) будь-якої новішої.
+
+ GNU Emacs поширюється зі сподіванням, що він стане в нагоді, але БЕЗ
+ ЖОДНИХ ГАРАНТІЙ; без навіть уявної гарантії КОМЕРЦІЙНОЇ ПРИДАТНОСТІ
+ чи ВІДПОВІДНОСТІ БУДЬ-ЯКОМУ ПЕВНОМУ ЗАСТОСУВАННЮ. Докладніше про це
+ йдеться в Загальній громадській ліцензії GNU.
+
+ Ви мали отримати копію Загальної громадської ліцензії GNU разом із
+ GNU Emacs. Якщо ні, перегляньте <https://www.gnu.org/licenses/>.
+
+Будь ласка, прочитайте файл COPYING і поширте після цього копії
+GNU Emacs вашим подругам і друзям. Зупинімо гальмування розвитку
+програмного забезпечення (так звану «власність» над ним),
+використовуючи, пишучи й поширюючи вільні програми!
diff --git a/leim/Makefile.in b/leim/Makefile.in
index 29b9f3b2f86..fbd733b7f66 100644
--- a/leim/Makefile.in
+++ b/leim/Makefile.in
@@ -128,7 +128,6 @@ leim-list.el: ${leimdir}/leim-list.el
${leimdir}/leim-list.el: ${srcdir}/leim-ext.el ${TIT_MISC}
$(AM_V_GEN)rm -f $@
$(AM_V_at)${RUN_EMACS} -l international/quail \
- --eval "(setq max-specpdl-size 5000)" \
--eval "(update-leim-list-file (unmsys--file-name \"${leimdir}\"))"
$(AM_V_at)sed -n -e '/^[^;]/p' -e 's/^;\(;*\)inc /;\1 /p' < $< >> $@
@@ -139,7 +138,6 @@ ${leimdir}/ja-dic/ja-dic.el: | $(leimdir)/ja-dic
generate-ja-dic: ${leimdir}/ja-dic/ja-dic.el
${leimdir}/ja-dic/ja-dic.el: $(srcdir)/SKK-DIC/SKK-JISYO.L
$(AM_V_GEN)$(RUN_EMACS) -batch -l ja-dic-cnv \
- --eval "(setq max-specpdl-size 5000)" \
-f batch-skkdic-convert -dir "$(leimdir)/ja-dic" $(JA_DIC_NO_REDUCTION_OPTION) "$<"
${srcdir}/../lisp/language/pinyin.el: ${srcdir}/MISC-DIC/pinyin.map
diff --git a/lib-src/Makefile.in b/lib-src/Makefile.in
index cf4659fc2c1..cfad3fc3941 100644
--- a/lib-src/Makefile.in
+++ b/lib-src/Makefile.in
@@ -306,8 +306,8 @@ $(DESTDIR)${archlibdir}: all
$(info $ )
$(info Installing utilities run internally by Emacs.)
umask 022 && ${MKDIR_P} "$(DESTDIR)${archlibdir}"
- exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd` && \
- if [ "$$exp_archlibdir" != "`/bin/pwd`" ]; then \
+ exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && pwd -P` && \
+ if [ "$$exp_archlibdir" != "`pwd -P`" ]; then \
for file in ${UTILITIES}; do \
$(INSTALL_PROGRAM) $(INSTALL_STRIP) $$file \
"$(DESTDIR)${archlibdir}/$$file" || exit; \
@@ -333,8 +333,8 @@ $(DESTDIR)${archlibdir}: all
chmod u=rwx,g=rwx,o=rx "$(DESTDIR)${gamedir}"
endif
endif
- exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd` && \
- if [ "$$exp_archlibdir" != "`cd ${srcdir} && /bin/pwd`" ]; then \
+ exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && pwd -P` && \
+ if [ "$$exp_archlibdir" != "`cd ${srcdir} && pwd -P`" ]; then \
for file in ${SCRIPTS}; do \
$(INSTALL_SCRIPT) ${srcdir}/$$file \
"$(DESTDIR)${archlibdir}/$$file" || exit; \
diff --git a/lib-src/seccomp-filter.c b/lib-src/seccomp-filter.c
index 9f0de7d64f8..7e54b878a22 100644
--- a/lib-src/seccomp-filter.c
+++ b/lib-src/seccomp-filter.c
@@ -39,7 +39,6 @@ variants of those files that can be used to sandbox Emacs before
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
-#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
@@ -60,7 +59,6 @@ variants of those files that can be used to sandbox Emacs before
#include <unistd.h>
#include <attribute.h>
-#include <verify.h>
#ifndef ARCH_CET_STATUS
#define ARCH_CET_STATUS 0x3001
@@ -71,19 +69,16 @@ fail (int error, const char *format, ...)
{
va_list ap;
va_start (ap, format);
+ vfprintf (stderr, format, ap);
+ va_end (ap);
if (error == 0)
- {
- vfprintf (stderr, format, ap);
- fputc ('\n', stderr);
- }
+ fputc ('\n', stderr);
else
{
- char buffer[1000];
- vsnprintf (buffer, sizeof buffer, format, ap);
+ fputs (": ", stderr);
errno = error;
- perror (buffer);
+ perror (NULL);
}
- va_end (ap);
fflush (NULL);
exit (EXIT_FAILURE);
}
@@ -168,12 +163,12 @@ main (int argc, char **argv)
set_attribute (SCMP_FLTATR_CTL_NNP, 1);
set_attribute (SCMP_FLTATR_CTL_TSYNC, 1);
- verify (CHAR_BIT == 8);
- verify (sizeof (int) == 4 && INT_MIN == INT32_MIN
- && INT_MAX == INT32_MAX);
- verify (sizeof (long) == 8 && LONG_MIN == INT64_MIN
- && LONG_MAX == INT64_MAX);
- verify (sizeof (void *) == 8);
+ static_assert (CHAR_BIT == 8);
+ static_assert (sizeof (int) == 4 && INT_MIN == INT32_MIN
+ && INT_MAX == INT32_MAX);
+ static_assert (sizeof (long) == 8 && LONG_MIN == INT64_MIN
+ && LONG_MAX == INT64_MAX);
+ static_assert (sizeof (void *) == 8);
assert ((uintptr_t) NULL == 0);
/* Allow a clean exit. */
@@ -183,8 +178,8 @@ main (int argc, char **argv)
/* Allow `mmap' and friends. This is necessary for dynamic loading,
reading the portable dump file, and thread creation. We don't
allow pages to be both writable and executable. */
- verify (MAP_PRIVATE != 0);
- verify (MAP_SHARED != 0);
+ static_assert (MAP_PRIVATE != 0);
+ static_assert (MAP_SHARED != 0);
RULE (SCMP_ACT_ALLOW, SCMP_SYS (mmap),
SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
~(PROT_NONE | PROT_READ | PROT_WRITE)),
@@ -211,6 +206,9 @@ main (int argc, char **argv)
SCMP_A2_32 (SCMP_CMP_MASKED_EQ,
~(PROT_NONE | PROT_READ | PROT_WRITE), 0));
+ /* Allow restartable sequences. The dynamic linker uses them. */
+ RULE (SCMP_ACT_ALLOW, SCMP_SYS (rseq));
+
/* Futexes are used everywhere. */
RULE (SCMP_ACT_ALLOW, SCMP_SYS (futex),
SCMP_A1_32 (SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE));
@@ -223,6 +221,7 @@ main (int argc, char **argv)
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getuid));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (geteuid));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpid));
+ RULE (SCMP_ACT_ALLOW, SCMP_SYS (gettid));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (getpgrp));
/* Allow operations on open file descriptors. File descriptors are
@@ -256,9 +255,9 @@ main (int argc, char **argv)
/* Allow opening files, assuming they are only opened for
reading. */
- verify (O_WRONLY != 0);
- verify (O_RDWR != 0);
- verify (O_CREAT != 0);
+ static_assert (O_WRONLY != 0);
+ static_assert (O_RDWR != 0);
+ static_assert (O_CREAT != 0);
RULE (SCMP_ACT_ALLOW, SCMP_SYS (open),
SCMP_A1_32 (SCMP_CMP_MASKED_EQ,
~(O_RDONLY | O_BINARY | O_CLOEXEC | O_PATH
@@ -329,6 +328,8 @@ main (int argc, char **argv)
| CLONE_SETTLS | CLONE_PARENT_SETTID
| CLONE_CHILD_CLEARTID),
0));
+ /* glibc 2.34+ pthread_create uses clone3. */
+ RULE (SCMP_ACT_ALLOW, SCMP_SYS (clone3));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (sigaltstack));
RULE (SCMP_ACT_ALLOW, SCMP_SYS (set_robust_list));
diff --git a/lib/acl-internal.h b/lib/acl-internal.h
index 93533762dd0..94553fab254 100644
--- a/lib/acl-internal.h
+++ b/lib/acl-internal.h
@@ -19,7 +19,6 @@
#include "acl.h"
-#include <stdbool.h>
#include <stdlib.h>
/* All systems define the ACL related API in <sys/acl.h>. */
diff --git a/lib/acl.h b/lib/acl.h
index f4d0df80618..0be6ef1cea3 100644
--- a/lib/acl.h
+++ b/lib/acl.h
@@ -20,7 +20,6 @@
#ifndef _GL_ACL_H
#define _GL_ACL_H 1
-#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/lib/assert.in.h b/lib/assert.in.h
new file mode 100644
index 00000000000..2c358ba62e7
--- /dev/null
+++ b/lib/assert.in.h
@@ -0,0 +1,27 @@
+/* Substitute for and wrapper around <assert.h>
+ Copyright (C) 2011-2022 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Do not guard the include, since <assert.h> is supposed to define
+ the assert macro each time it is included. */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#@INCLUDE_NEXT@ @NEXT_ASSERT_H@
+
+/* The definition of static_assert is copied here. */
diff --git a/lib/c-ctype.h b/lib/c-ctype.h
index 1a4f603898f..1202ff8a363 100644
--- a/lib/c-ctype.h
+++ b/lib/c-ctype.h
@@ -23,8 +23,6 @@
#ifndef C_CTYPE_H
#define C_CTYPE_H
-#include <stdbool.h>
-
#ifndef _GL_INLINE_HEADER_BEGIN
#error "Please include config.h first."
#endif
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index a7fa7feb62e..8c3d7f7cf80 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -30,7 +30,6 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
diff --git a/lib/cloexec.h b/lib/cloexec.h
index 7a22d775327..15d2d5efe20 100644
--- a/lib/cloexec.h
+++ b/lib/cloexec.h
@@ -15,8 +15,6 @@
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
-#include <stdbool.h>
-
/* Set the 'FD_CLOEXEC' flag of DESC if VALUE is true,
or clear the flag if VALUE is false.
Return 0 on success, or -1 on error with 'errno' set.
diff --git a/lib/close-stream.c b/lib/close-stream.c
index 9b0e97b271d..0fdca79bf8e 100644
--- a/lib/close-stream.c
+++ b/lib/close-stream.c
@@ -20,7 +20,6 @@
#include "close-stream.h"
#include <errno.h>
-#include <stdbool.h>
#include "fpending.h"
diff --git a/lib/count-leading-zeros.h b/lib/count-leading-zeros.h
index 354641af0a2..4b4f5d4f9a1 100644
--- a/lib/count-leading-zeros.h
+++ b/lib/count-leading-zeros.h
@@ -43,13 +43,17 @@ extern "C" {
# define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
#elif _MSC_VER
-# pragma intrinsic _BitScanReverse
-# pragma intrinsic _BitScanReverse64
+# pragma intrinsic (_BitScanReverse)
+# if defined _M_X64
+# pragma intrinsic (_BitScanReverse64)
+# endif
# define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
do \
{ \
unsigned long result; \
- return MSC_BUILTIN (&result, x) ? result : CHAR_BIT * sizeof x; \
+ if (MSC_BUILTIN (&result, x)) \
+ return CHAR_BIT * sizeof x - 1 - result; \
+ return CHAR_BIT * sizeof x; \
} \
while (0)
#else
@@ -109,8 +113,18 @@ count_leading_zeros_l (unsigned long int x)
COUNT_LEADING_ZEROS_INLINE int
count_leading_zeros_ll (unsigned long long int x)
{
+#if (defined _MSC_VER && !defined __clang__) && !defined _M_X64
+ /* 32-bit MSVC does not have _BitScanReverse64, only _BitScanReverse. */
+ unsigned long result;
+ if (_BitScanReverse (&result, (unsigned long) (x >> 32)))
+ return CHAR_BIT * sizeof x - 1 - 32 - result;
+ if (_BitScanReverse (&result, (unsigned long) x))
+ return CHAR_BIT * sizeof x - 1 - result;
+ return CHAR_BIT * sizeof x;
+#else
COUNT_LEADING_ZEROS (__builtin_clzll, _BitScanReverse64,
unsigned long long int);
+#endif
}
#ifdef __cplusplus
diff --git a/lib/count-trailing-zeros.h b/lib/count-trailing-zeros.h
index 9a989a43245..61fbdf29801 100644
--- a/lib/count-trailing-zeros.h
+++ b/lib/count-trailing-zeros.h
@@ -43,8 +43,10 @@ extern "C" {
# define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
#elif _MSC_VER
-# pragma intrinsic _BitScanForward
-# pragma intrinsic _BitScanForward64
+# pragma intrinsic (_BitScanForward)
+# if defined _M_X64
+# pragma intrinsic (_BitScanForward64)
+# endif
# define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
do \
{ \
@@ -101,8 +103,18 @@ count_trailing_zeros_l (unsigned long int x)
COUNT_TRAILING_ZEROS_INLINE int
count_trailing_zeros_ll (unsigned long long int x)
{
+#if (defined _MSC_VER && !defined __clang__) && !defined _M_X64
+ /* 32-bit MSVC does not have _BitScanForward64, only _BitScanForward. */
+ unsigned long result;
+ if (_BitScanForward (&result, (unsigned long) x))
+ return result;
+ if (_BitScanForward (&result, (unsigned long) (x >> 32)))
+ return result + 32;
+ return CHAR_BIT * sizeof x;
+#else
COUNT_TRAILING_ZEROS (__builtin_ctzll, _BitScanForward64,
unsigned long long int);
+#endif
}
#ifdef __cplusplus
diff --git a/lib/diffseq.h b/lib/diffseq.h
index 0f76ea1d5ad..a8b0e7bd408 100644
--- a/lib/diffseq.h
+++ b/lib/diffseq.h
@@ -70,7 +70,6 @@
Before including this file, you also need to include:
#include <limits.h>
- #include <stdbool.h>
#include "minmax.h"
*/
diff --git a/lib/filevercmp.c b/lib/filevercmp.c
index 7e54793e613..844505a6bf7 100644
--- a/lib/filevercmp.c
+++ b/lib/filevercmp.c
@@ -20,11 +20,9 @@
#include <config.h>
#include "filevercmp.h"
-#include <stdbool.h>
#include <c-ctype.h>
#include <limits.h>
#include <idx.h>
-#include <verify.h>
/* Return the length of a prefix of S that corresponds to the suffix
defined by this extended regular expression in the C locale:
@@ -75,7 +73,7 @@ order (char const *s, idx_t pos, idx_t len)
return -2;
else
{
- verify (UCHAR_MAX <= (INT_MAX - 1 - 2) / 2);
+ static_assert (UCHAR_MAX <= (INT_MAX - 1 - 2) / 2);
return c + UCHAR_MAX + 1;
}
}
diff --git a/lib/fsusage.h b/lib/fsusage.h
index 0443d19f922..27085b7b41e 100644
--- a/lib/fsusage.h
+++ b/lib/fsusage.h
@@ -22,7 +22,6 @@
# define FSUSAGE_H_
# include <stdint.h>
-# include <stdbool.h>
struct fs_usage
{
diff --git a/lib/getloadavg.c b/lib/getloadavg.c
index 37e82808671..1fddee97afd 100644
--- a/lib/getloadavg.c
+++ b/lib/getloadavg.c
@@ -82,7 +82,6 @@
#include <stdlib.h>
#include <errno.h>
-#include <stdbool.h>
#include <stdio.h>
# include <sys/types.h>
diff --git a/lib/getrandom.c b/lib/getrandom.c
index e1468730933..c05a48167ed 100644
--- a/lib/getrandom.c
+++ b/lib/getrandom.c
@@ -23,7 +23,6 @@
#include <errno.h>
#include <fcntl.h>
-#include <stdbool.h>
#include <unistd.h>
#if defined _WIN32 && ! defined __CYGWIN__
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 5bb78740d6a..04644bdabe3 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -60,7 +60,6 @@
# --avoid=sigprocmask \
# --avoid=stat \
# --avoid=stdarg \
-# --avoid=stdbool \
# --avoid=threadlib \
# --avoid=tzset \
# --avoid=unsetenv \
@@ -147,6 +146,7 @@
# stat-time \
# std-gnu11 \
# stdalign \
+# stdbool \
# stddef \
# stdio \
# stpcpy \
@@ -180,6 +180,7 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
AR = @AR@
ARFLAGS = @ARFLAGS@
+ASSERT_H = @ASSERT_H@
AUTO_DEPEND = @AUTO_DEPEND@
AWK = @AWK@
BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
@@ -307,6 +308,7 @@ GL_COND_OBJ_TIME_RZ_CONDITION = @GL_COND_OBJ_TIME_RZ_CONDITION@
GL_COND_OBJ_TIME_R_CONDITION = @GL_COND_OBJ_TIME_R_CONDITION@
GL_COND_OBJ_UTIMENSAT_CONDITION = @GL_COND_OBJ_UTIMENSAT_CONDITION@
GL_GENERATE_ALLOCA_H_CONDITION = @GL_GENERATE_ALLOCA_H_CONDITION@
+GL_GENERATE_ASSERT_H_CONDITION = @GL_GENERATE_ASSERT_H_CONDITION@
GL_GENERATE_BYTESWAP_H_CONDITION = @GL_GENERATE_BYTESWAP_H_CONDITION@
GL_GENERATE_ERRNO_H_CONDITION = @GL_GENERATE_ERRNO_H_CONDITION@
GL_GENERATE_EXECINFO_H_CONDITION = @GL_GENERATE_EXECINFO_H_CONDITION@
@@ -951,6 +953,8 @@ MKDIR_P = @MKDIR_P@
MODULES_OBJ = @MODULES_OBJ@
MODULES_SECONDARY_SUFFIX = @MODULES_SECONDARY_SUFFIX@
MODULES_SUFFIX = @MODULES_SUFFIX@
+NEXT_ASSERT_H = @NEXT_ASSERT_H@
+NEXT_AS_FIRST_DIRECTIVE_ASSERT_H = @NEXT_AS_FIRST_DIRECTIVE_ASSERT_H@
NEXT_AS_FIRST_DIRECTIVE_DIRENT_H = @NEXT_AS_FIRST_DIRECTIVE_DIRENT_H@
NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@
NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
@@ -1440,6 +1444,39 @@ EXTRA_DIST += allocator.h
endif
## end gnulib module allocator
+## begin gnulib module assert-h
+ifeq (,$(OMIT_GNULIB_MODULE_assert-h))
+
+BUILT_SOURCES += $(ASSERT_H)
+
+# We need the following in order to create <assert.h> when the system
+# doesn't have one that works with the given compiler.
+ifneq (,$(GL_GENERATE_ASSERT_H_CONDITION))
+assert.h: assert.in.h verify.h $(top_builddir)/config.status
+ $(gl_V_at){ $(SED_HEADER_STDOUT) \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_ASSERT_H''@|$(NEXT_ASSERT_H)|g' \
+ < $(srcdir)/assert.in.h && \
+ sed -e '/@assert.h omit start@/,/@assert.h omit end@/d' \
+ -e 's|_gl_verify|_gl_static_assert|g' \
+ -e 's|_GL_VERIFY|_GL_STATIC_ASSERT|g' \
+ -e 's|_GL\(_STATIC_ASSERT_H\)|_GL\1|g' \
+ < $(srcdir)/verify.h; \
+ } > $@-t
+ $(AM_V_at)mv $@-t $@
+else
+assert.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += assert.h assert.h-t
+
+EXTRA_DIST += assert.in.h verify.h
+
+endif
+## end gnulib module assert-h
+
## begin gnulib module at-internal
ifeq (,$(OMIT_GNULIB_MODULE_at-internal))
diff --git a/lib/malloc/dynarray.h b/lib/malloc/dynarray.h
index f16fd950df6..df1aa4167dd 100644
--- a/lib/malloc/dynarray.h
+++ b/lib/malloc/dynarray.h
@@ -94,7 +94,6 @@
#ifndef _DYNARRAY_H
#define _DYNARRAY_H
-#include <stdbool.h>
#include <stddef.h>
#include <string.h>
diff --git a/lib/md5.c b/lib/md5.c
index 57489ed74c5..c16ac4a93a8 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -27,7 +27,6 @@
#endif
#include "md5.h"
-#include <stdalign.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
diff --git a/lib/mini-gmp.c b/lib/mini-gmp.c
index 95f067f82d6..ea037b801dc 100644
--- a/lib/mini-gmp.c
+++ b/lib/mini-gmp.c
@@ -1,8 +1,9 @@
/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
Contributed to the GNU project by Niels Möller
+ Additional functionalities and improvements by Marco Bodrato.
-Copyright 1991-1997, 1999-2021 Free Software Foundation, Inc.
+Copyright 1991-1997, 1999-2022 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
@@ -3098,7 +3099,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
if (en == 0)
{
- mpz_set_ui (r, 1);
+ mpz_set_ui (r, mpz_cmpabs_ui (m, 1));
return;
}
diff --git a/lib/nanosleep.c b/lib/nanosleep.c
index 446794edc0b..55d6fa650e3 100644
--- a/lib/nanosleep.c
+++ b/lib/nanosleep.c
@@ -23,9 +23,7 @@
#include <time.h>
#include "intprops.h"
-#include "verify.h"
-#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/select.h>
@@ -59,7 +57,7 @@ nanosleep (const struct timespec *requested_delay,
{
/* Verify that time_t is large enough. */
- verify (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60);
+ static_assert (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60);
const time_t limit = 24 * 24 * 60 * 60;
time_t seconds = requested_delay->tv_sec;
struct timespec intermediate;
diff --git a/lib/nstrftime.c b/lib/nstrftime.c
index c1dd5542478..37034eb9fb7 100644
--- a/lib/nstrftime.c
+++ b/lib/nstrftime.c
@@ -65,7 +65,6 @@ extern char *tzname[];
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
-#include <stdbool.h>
#include "attribute.h"
#include <intprops.h>
diff --git a/lib/openat.h b/lib/openat.h
index 56919ef8dc4..c2f64ff50e2 100644
--- a/lib/openat.h
+++ b/lib/openat.h
@@ -24,7 +24,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <stdbool.h>
#ifndef _GL_INLINE_HEADER_BEGIN
#error "Please include config.h first."
diff --git a/lib/pipe2.c b/lib/pipe2.c
index 400aff001a2..a3cbb7f2611 100644
--- a/lib/pipe2.c
+++ b/lib/pipe2.c
@@ -23,7 +23,6 @@
#include <fcntl.h>
#include "binary-io.h"
-#include "verify.h"
#if GNULIB_defined_O_NONBLOCK
# include "nonblocking.h"
@@ -95,7 +94,7 @@ pipe2 (int fd[2], int flags)
}
# else
{
- verify (O_NONBLOCK == 0);
+ static_assert (O_NONBLOCK == 0);
}
# endif
diff --git a/lib/rawmemchr.c b/lib/rawmemchr.c
index ea68c1bfc6a..bdd7307de4b 100644
--- a/lib/rawmemchr.c
+++ b/lib/rawmemchr.c
@@ -23,10 +23,8 @@
#if !HAVE_RAWMEMCHR
# include <limits.h>
-# include <stdalign.h>
# include <stdint.h>
-# include "verify.h"
/* Find the first occurrence of C in S. */
void *
@@ -36,7 +34,7 @@ rawmemchr (const void *s, int c_in)
typedef uintptr_t longword;
/* If you change the "uintptr_t", you should change UINTPTR_WIDTH to match.
This verifies that the type does not have padding bits. */
- verify (UINTPTR_WIDTH == UCHAR_WIDTH * sizeof (longword));
+ static_assert (UINTPTR_WIDTH == UCHAR_WIDTH * sizeof (longword));
const unsigned char *char_ptr;
unsigned char c = c_in;
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index 57a455b1f43..784d2d45866 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -29,7 +29,6 @@
#include <locale.h>
#include <wchar.h>
#include <wctype.h>
-#include <stdbool.h>
#include <stdint.h>
#ifndef _LIBC
diff --git a/lib/sha1.c b/lib/sha1.c
index 79e50ba0b03..5a18213edc1 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -29,7 +29,6 @@
#endif
#include "sha1.h"
-#include <stdalign.h>
#include <stdint.h>
#include <string.h>
diff --git a/lib/sha256.c b/lib/sha256.c
index c9ca618c67e..60cd763612d 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -28,7 +28,6 @@
#endif
#include "sha256.h"
-#include <stdalign.h>
#include <stdint.h>
#include <string.h>
diff --git a/lib/sha512.c b/lib/sha512.c
index 6776bb464d8..fd17a7dc760 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -28,7 +28,6 @@
#endif
#include "sha512.h"
-#include <stdalign.h>
#include <stdint.h>
#include <string.h>
diff --git a/lib/signal.in.h b/lib/signal.in.h
index 640b5022f5f..c0d4848db0a 100644
--- a/lib/signal.in.h
+++ b/lib/signal.in.h
@@ -55,13 +55,21 @@
#ifndef _@GUARD_PREFIX@_SIGNAL_H
#define _@GUARD_PREFIX@_SIGNAL_H
-/* Mac OS X 10.3, FreeBSD 6.4, OpenBSD 3.8, OSF/1 4.0, Solaris 2.6, Android,
+/* For testing the OpenBSD version. */
+#if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \
+ && defined __OpenBSD__
+# include <sys/param.h>
+#endif
+
+/* Mac OS X 10.3, FreeBSD < 8.0, OpenBSD < 5.1, OSF/1 4.0, Solaris 2.6, Android,
OS/2 kLIBC declare pthread_sigmask in <pthread.h>, not in <signal.h>.
But avoid namespace pollution on glibc systems.*/
#if (@GNULIB_PTHREAD_SIGMASK@ || defined GNULIB_POSIXCHECK) \
&& ((defined __APPLE__ && defined __MACH__) \
- || defined __FreeBSD__ || defined __OpenBSD__ || defined __osf__ \
- || defined __sun || defined __ANDROID__ || defined __KLIBC__) \
+ || (defined __FreeBSD__ && __FreeBSD__ < 8) \
+ || (defined __OpenBSD__ && OpenBSD < 201205) \
+ || defined __osf__ || defined __sun || defined __ANDROID__ \
+ || defined __KLIBC__) \
&& ! defined __GLIBC__
# include <pthread.h>
#endif
diff --git a/lib/stdalign.in.h b/lib/stdalign.in.h
index 3b117df11fe..58fd245c627 100644
--- a/lib/stdalign.in.h
+++ b/lib/stdalign.in.h
@@ -42,10 +42,7 @@
'-malign-double' is used.
The result cannot be used as a value for an 'enum' constant, if you
- want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc.
-
- Include <stddef.h> for offsetof. */
-#include <stddef.h>
+ want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. */
/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
standard headers, defines conflicting implementations of _Alignas
@@ -61,17 +58,19 @@
&& !defined __clang__) \
|| (defined __clang__ && __clang_major__ < 8))
# ifdef __cplusplus
-# if 201103 <= __cplusplus
+# if (201103 <= __cplusplus || defined _MSC_VER)
# define _Alignof(type) alignof (type)
# else
template <class __t> struct __alignof_helper { char __a; __t __b; };
# define _Alignof(type) offsetof (__alignof_helper<type>, __b)
+# define _GL_STDALIGN_NEEDS_STDDEF 1
# endif
# else
# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b)
+# define _GL_STDALIGN_NEEDS_STDDEF 1
# endif
#endif
-#if ! (defined __cplusplus && 201103 <= __cplusplus)
+#if ! (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))
# define alignof _Alignof
#endif
#define __alignof_is_defined 1
@@ -102,7 +101,7 @@
*/
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
-# if defined __cplusplus && 201103 <= __cplusplus
+# if defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)
# define _Alignas(a) alignas (a)
# elif (!defined __attribute__ \
&& ((defined __APPLE__ && defined __MACH__ \
@@ -116,12 +115,19 @@
# define _Alignas(a) __declspec (align (a))
# endif
#endif
-#if ((defined _Alignas && ! (defined __cplusplus && 201103 <= __cplusplus)) \
+#if ((defined _Alignas \
+ && !(defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))) \
|| (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__))
# define alignas _Alignas
#endif
-#if defined alignas || (defined __cplusplus && 201103 <= __cplusplus)
+#if (defined alignas \
+ || (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)))
# define __alignas_is_defined 1
#endif
+/* Include <stddef.h> if needed for offsetof. */
+#if _GL_STDALIGN_NEEDS_STDDEF
+# include <stddef.h>
+#endif
+
#endif /* _GL_STDALIGN_H */
diff --git a/lib/stdckdint.in.h b/lib/stdckdint.in.h
index 90fa62e5966..762d3fdb790 100644
--- a/lib/stdckdint.in.h
+++ b/lib/stdckdint.in.h
@@ -20,8 +20,6 @@
#include "intprops-internal.h"
-#include <stdbool.h>
-
/* Store into *R the low-order bits of A + B, A - B, A * B, respectively.
Return 1 if the result overflows, 0 otherwise.
A, B, and *R can have any integer type other than char, bool, a
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index a86643c3ca3..8e0a609f1f7 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -226,7 +226,7 @@ _GL_FUNCDECL_SYS (aligned_alloc, void *,
_GL_CXXALIAS_SYS (aligned_alloc, void *, (size_t alignment, size_t size));
# endif
# endif
-# if @HAVE_ALIGNED_ALLOC@
+# if (__GLIBC__ >= 2) && @HAVE_ALIGNED_ALLOC@
_GL_CXXALIASWARN (aligned_alloc);
# endif
#else
@@ -1363,7 +1363,9 @@ _GL_CXXALIAS_SYS (strtol, long,
(const char *restrict string, char **restrict endptr,
int base));
# endif
+# if __GLIBC__ >= 2
_GL_CXXALIASWARN (strtol);
+# endif
#elif defined GNULIB_POSIXCHECK
# undef strtol
# if HAVE_RAW_DECL_STRTOL
@@ -1444,7 +1446,9 @@ _GL_CXXALIAS_SYS (strtoul, unsigned long,
(const char *restrict string, char **restrict endptr,
int base));
# endif
+# if __GLIBC__ >= 2
_GL_CXXALIASWARN (strtoul);
+# endif
#elif defined GNULIB_POSIXCHECK
# undef strtoul
# if HAVE_RAW_DECL_STRTOUL
diff --git a/lib/string.in.h b/lib/string.in.h
index 3996da9fcb5..e56f6db0c9c 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -943,7 +943,9 @@ _GL_FUNCDECL_SYS (mbslen, size_t, (const char *string)
_GL_ARG_NONNULL ((1)));
_GL_CXXALIAS_SYS (mbslen, size_t, (const char *string));
# endif
+# if __GLIBC__ >= 2
_GL_CXXALIASWARN (mbslen);
+# endif
#endif
#if @GNULIB_MBSNLEN@
diff --git a/lib/strtoimax.c b/lib/strtoimax.c
index cad12d0d9be..29d16d29cef 100644
--- a/lib/strtoimax.c
+++ b/lib/strtoimax.c
@@ -25,8 +25,6 @@
#include <stdlib.h>
-#include "verify.h"
-
#ifdef UNSIGNED
# ifndef HAVE_DECL_STRTOULL
"this configure-time declaration test was not run"
@@ -62,8 +60,8 @@ long long int strtoll (char const *, char **, int);
Int
Strtoimax (char const *ptr, char **endptr, int base)
{
- verify (sizeof (Int) == sizeof (Unsigned long int)
- || sizeof (Int) == sizeof (Unsigned long long int));
+ static_assert (sizeof (Int) == sizeof (Unsigned long int)
+ || sizeof (Int) == sizeof (Unsigned long long int));
if (sizeof (Int) != sizeof (Unsigned long int))
return Strtoll (ptr, endptr, base);
diff --git a/lib/sys_random.in.h b/lib/sys_random.in.h
index e730e6139f8..c91bcd2cd04 100644
--- a/lib/sys_random.in.h
+++ b/lib/sys_random.in.h
@@ -84,7 +84,9 @@ _GL_FUNCDECL_SYS (getrandom, ssize_t,
_GL_CXXALIAS_SYS (getrandom, ssize_t,
(void *buffer, size_t length, unsigned int flags));
# endif
+# if __GLIBC__ + (__GLIBC_MINOR__ >= 25) > 2
_GL_CXXALIASWARN (getrandom);
+# endif
#elif defined GNULIB_POSIXCHECK
# undef getrandom
# if HAVE_RAW_DECL_GETRANDOM
diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h
index 2bd0e0f79a8..860e957fe0f 100644
--- a/lib/sys_select.in.h
+++ b/lib/sys_select.in.h
@@ -82,9 +82,10 @@
of 'struct timeval', and no definition of this type.
Also, Mac OS X, AIX, HP-UX, IRIX, Solaris, Interix declare select()
in <sys/time.h>.
- But avoid namespace pollution on glibc systems and "unknown type
- name" problems on Cygwin. */
-# if !(defined __GLIBC__ || defined __CYGWIN__)
+ But avoid namespace pollution on glibc systems, a circular include
+ <sys/select.h> -> <sys/time.h> -> <sys/select.h> on FreeBSD 13.1, and
+ "unknown type name" problems on Cygwin. */
+# if !(defined __GLIBC__ || defined __FreeBSD__ || defined __CYGWIN__)
# include <sys/time.h>
# endif
@@ -287,7 +288,9 @@ _GL_CXXALIAS_SYS_CAST (pselect, int,
struct timespec const *restrict,
const sigset_t *restrict));
# endif
+# if __GLIBC__ >= 2
_GL_CXXALIASWARN (pselect);
+# endif
#elif defined GNULIB_POSIXCHECK
# undef pselect
# if HAVE_RAW_DECL_PSELECT
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index 714c3cb189e..0ec320f58c0 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -596,44 +596,6 @@ _GL_WARN_ON_USE (lchmod, "lchmod is unportable - "
#endif
-#if @GNULIB_LSTAT@
-# if ! @HAVE_LSTAT@
-/* mingw does not support symlinks, therefore it does not have lstat. But
- without links, stat does just fine. */
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# define lstat stat
-# endif
-_GL_CXXALIAS_RPL_1 (lstat, stat, int,
- (const char *restrict name, struct stat *restrict buf));
-# elif @REPLACE_LSTAT@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef lstat
-# define lstat rpl_lstat
-# endif
-_GL_FUNCDECL_RPL (lstat, int,
- (const char *restrict name, struct stat *restrict buf)
- _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (lstat, int,
- (const char *restrict name, struct stat *restrict buf));
-# else
-_GL_CXXALIAS_SYS (lstat, int,
- (const char *restrict name, struct stat *restrict buf));
-# endif
-# if @HAVE_LSTAT@
-_GL_CXXALIASWARN (lstat);
-# endif
-#elif @GNULIB_OVERRIDES_STRUCT_STAT@
-# undef lstat
-# define lstat lstat_used_without_requesting_gnulib_module_lstat
-#elif defined GNULIB_POSIXCHECK
-# undef lstat
-# if HAVE_RAW_DECL_LSTAT
-_GL_WARN_ON_USE (lstat, "lstat is unportable - "
- "use gnulib module lstat for portability");
-# endif
-#endif
-
-
#if @GNULIB_MKDIR@
# if @REPLACE_MKDIR@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
@@ -895,6 +857,44 @@ _GL_WARN_ON_USE (stat, "stat is unportable - "
#endif
+#if @GNULIB_LSTAT@
+# if ! @HAVE_LSTAT@
+/* mingw does not support symlinks, therefore it does not have lstat. But
+ without links, stat does just fine. */
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define lstat stat
+# endif
+_GL_CXXALIAS_RPL_1 (lstat, stat, int,
+ (const char *restrict name, struct stat *restrict buf));
+# elif @REPLACE_LSTAT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef lstat
+# define lstat rpl_lstat
+# endif
+_GL_FUNCDECL_RPL (lstat, int,
+ (const char *restrict name, struct stat *restrict buf)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (lstat, int,
+ (const char *restrict name, struct stat *restrict buf));
+# else
+_GL_CXXALIAS_SYS (lstat, int,
+ (const char *restrict name, struct stat *restrict buf));
+# endif
+# if @HAVE_LSTAT@
+_GL_CXXALIASWARN (lstat);
+# endif
+#elif @GNULIB_OVERRIDES_STRUCT_STAT@
+# undef lstat
+# define lstat lstat_used_without_requesting_gnulib_module_lstat
+#elif defined GNULIB_POSIXCHECK
+# undef lstat
+# if HAVE_RAW_DECL_LSTAT
+_GL_WARN_ON_USE (lstat, "lstat is unportable - "
+ "use gnulib module lstat for portability");
+# endif
+#endif
+
+
#if @GNULIB_MDA_UMASK@
/* On native Windows, map 'umask' to '_umask', so that -loldnames is not
required. In C++ with GNULIB_NAMESPACE, avoid differences between
diff --git a/lib/tempname.c b/lib/tempname.c
index 11b4796b34b..dbff638f701 100644
--- a/lib/tempname.c
+++ b/lib/tempname.c
@@ -20,7 +20,6 @@
# include "tempname.h"
#endif
-#include <stdbool.h>
#include <errno.h>
#include <stdio.h>
diff --git a/lib/time.in.h b/lib/time.in.h
index 6d4c7719636..6aa67498f57 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -435,8 +435,10 @@ _GL_WARN_ON_USE (asctime, "asctime can overrun buffers in some cases - "
# endif
# if defined GNULIB_POSIXCHECK
# undef asctime_r
+# if HAVE_RAW_DECL_ASCTIME_R
_GL_WARN_ON_USE (asctime_r, "asctime_r can overrun buffers in some cases - "
"better use strftime (or even sprintf) instead");
+# endif
# endif
# if defined GNULIB_POSIXCHECK
# undef ctime
@@ -445,8 +447,10 @@ _GL_WARN_ON_USE (ctime, "ctime can overrun buffers in some cases - "
# endif
# if defined GNULIB_POSIXCHECK
# undef ctime_r
+# if HAVE_RAW_DECL_CTIME_R
_GL_WARN_ON_USE (ctime_r, "ctime_r can overrun buffers in some cases - "
"better use strftime (or even sprintf) instead");
+# endif
# endif
#endif
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 1a91d3778e7..601ce5950e8 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -27,7 +27,6 @@
#include <time.h>
#include <errno.h>
-#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 57df09ecdf4..50f6e56550e 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1143,7 +1143,9 @@ _GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len)
# endif
_GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len));
# endif
+# if __GLIBC__ >= 2
_GL_CXXALIASWARN (getdomainname);
+# endif
#elif defined GNULIB_POSIXCHECK
# undef getdomainname
# if HAVE_RAW_DECL_GETDOMAINNAME
@@ -2055,7 +2057,7 @@ _GL_CXXALIAS_MDA_CAST (swab, void, (char *from, char *to, int n));
# else
# if defined __hpux /* HP-UX */
_GL_CXXALIAS_SYS (swab, void, (const char *from, char *to, int n));
-# elif defined __sun && !defined _XPG4 /* Solaris */
+# elif defined __sun && (defined __SunOS_5_10 || defined __XOPEN_OR_POSIX) && !defined _XPG4 /* Solaris */
_GL_CXXALIAS_SYS (swab, void, (const char *from, char *to, ssize_t n));
# else
_GL_CXXALIAS_SYS (swab, void, (const void *from, void *to, ssize_t n));
diff --git a/lib/utimens.c b/lib/utimens.c
index 2fa12518507..23b91809354 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -26,7 +26,6 @@
#include <errno.h>
#include <fcntl.h>
-#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
diff --git a/lib/verify.h b/lib/verify.h
index 47b6ee661b3..99af802993e 100644
--- a/lib/verify.h
+++ b/lib/verify.h
@@ -25,19 +25,19 @@
works as per C11. This is supported by GCC 4.6.0+ and by clang 4+.
Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as
- per C2x. This is supported by GCC 9.1+.
+ per C23. This is supported by GCC 9.1+.
Support compilers claiming conformance to the relevant standard,
and also support GCC when not pedantic. If we were willing to slow
'configure' down we could also use it with other compilers, but
since this affects only the quality of diagnostics, why bother? */
#ifndef __cplusplus
-# if (201112L <= __STDC_VERSION__ \
+# if (201112 <= __STDC_VERSION__ \
|| (!defined __STRICT_ANSI__ \
&& (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 5 <= __clang_major__)))
# define _GL_HAVE__STATIC_ASSERT 1
# endif
-# if (202000L <= __STDC_VERSION__ \
+# if (202000 <= __STDC_VERSION__ \
|| (!defined __STRICT_ANSI__ && 9 <= __GNUC__))
# define _GL_HAVE__STATIC_ASSERT1 1
# endif
@@ -202,12 +202,12 @@ template <int w>
This macro requires three or more arguments but uses at most the first
two, so that the _Static_assert macro optionally defined below supports
- both the C11 two-argument syntax and the C2x one-argument syntax.
+ both the C11 two-argument syntax and the C23 one-argument syntax.
Unfortunately, unlike C11, this implementation must appear as an
ordinary declaration, and cannot appear inside struct { ... }. */
-#if 200410 <= __cpp_static_assert
+#if 202311 <= __STDC_VERSION__ || 200410 <= __cpp_static_assert
# define _GL_VERIFY(R, DIAGNOSTIC, ...) static_assert (R, DIAGNOSTIC)
#elif defined _GL_HAVE__STATIC_ASSERT
# define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC)
@@ -223,11 +223,30 @@ template <int w>
/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */
#ifdef _GL_STATIC_ASSERT_H
# if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert
-# define _Static_assert(...) \
- _GL_VERIFY (__VA_ARGS__, "static assertion failed", -)
+# define _Static_assert(R, ...) \
+ _GL_VERIFY ((R), "static assertion failed", -)
# endif
-# if __cpp_static_assert < 201411 && !defined static_assert
-# define static_assert _Static_assert /* C11 requires this #define. */
+# if (!defined static_assert \
+ && __STDC_VERSION__ < 202311 \
+ && (!defined __cplusplus \
+ || (__cpp_static_assert < 201411 \
+ && __GNUG__ < 6 && __clang_major__ < 6)))
+# if defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__
+/* MSVC 14 in C++ mode supports the two-arguments static_assert but not
+ the one-argument static_assert, and it does not support _Static_assert.
+ We have to play preprocessor tricks to distinguish the two cases.
+ Since the MSVC preprocessor is not ISO C compliant (cf.
+ <https://stackoverflow.com/questions/5134523/>), the solution is specific
+ to MSVC. */
+# define _GL_EXPAND(x) x
+# define _GL_SA1(a1) static_assert ((a1), "static assertion failed")
+# define _GL_SA2 static_assert
+# define _GL_SA3 static_assert
+# define _GL_SA_PICK(x1,x2,x3,x4,...) x4
+# define static_assert(...) _GL_EXPAND(_GL_SA_PICK(__VA_ARGS__,_GL_SA3,_GL_SA2,_GL_SA1)) (__VA_ARGS__)
+# else
+# define static_assert _Static_assert /* C11 requires this #define. */
+# endif
# endif
#endif
@@ -303,7 +322,7 @@ template <int w>
# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
#elif 1200 <= _MSC_VER
# define assume(R) __assume (R)
-#elif 202311L <= __STDC_VERSION__
+#elif 202311 <= __STDC_VERSION__
# include <stddef.h>
# define assume(R) ((R) ? (void) 0 : unreachable ())
#elif (defined GCC_LINT || defined lint) && _GL_HAS_BUILTIN_TRAP
diff --git a/lisp/ChangeLog.10 b/lisp/ChangeLog.10
index 0b97a641099..6053ffa65aa 100644
--- a/lisp/ChangeLog.10
+++ b/lisp/ChangeLog.10
@@ -9490,7 +9490,7 @@
toolbar/rescan.pbm, toolbar/rescan.xpm, toolbar/show.pbm,
toolbar/show.xpm, toolbar/widen.pbm, toolbar/widen.xpm:
Upgraded to mh-e version 6.1.1. Full ChangeLog available in
- http://prdownloads.sourceforge.net/mh-e/mh-e-6.1.tgz?download .
+ https://prdownloads.sourceforge.net/mh-e/mh-e-6.1.tgz?download .
There were no user-visible changes in 6.1.1 from 6.1--only the
section of the Makefile that installs the files into Emacs was changed.
diff --git a/lisp/ChangeLog.14 b/lisp/ChangeLog.14
index c84e44536d2..686746abe0b 100644
--- a/lisp/ChangeLog.14
+++ b/lisp/ChangeLog.14
@@ -155,7 +155,7 @@
* epa.el (epa-decrypt-region): Detect encoding if
coding-system-for-read is not specified.
- <http://sourceforge.jp/ticket/browse.php?group_id=2267&tid=17018>
+ <https://sourceforge.jp/ticket/browse.php?group_id=2267&tid=17018>
(epa-verify-region): Ditto.
2009-06-04 Stefan Monnier <monnier@iro.umontreal.ca>
@@ -540,7 +540,7 @@
* epa-file.el (epa-file-decode-and-insert):
Use string-to-multibyte instead of set-buffer-multibyte.
- <http://sourceforge.jp/ticket/browse.php?group_id=2267&tid=15259>
+ <https://sourceforge.jp/ticket/browse.php?group_id=2267&tid=15259>
2009-04-18 Yann Hodique <yann.hodique@gmail.com> (tiny change)
diff --git a/lisp/ChangeLog.15 b/lisp/ChangeLog.15
index 53caf69e1ce..23e61ff7872 100644
--- a/lisp/ChangeLog.15
+++ b/lisp/ChangeLog.15
@@ -22762,7 +22762,7 @@
Automatically handle .xz suffix (XZ-compressed files), too.
* jka-cmpr-hook.el (jka-compr-compression-info-list): Add xz.
- XZ is the successor to LZMA: <http://tukaani.org/xz/>
+ XZ is the successor to LZMA: <https://tukaani.org/xz/>
2009-06-22 Dmitry Dzhus <dima@sphinx.net.ru>
Nick Roberts <nickrob@snap.net.nz>
diff --git a/lisp/ChangeLog.17 b/lisp/ChangeLog.17
index cebafe18aa0..df731fe9ed2 100644
--- a/lisp/ChangeLog.17
+++ b/lisp/ChangeLog.17
@@ -14039,7 +14039,7 @@
* epa-file.el (epa-file-write-region): Encode the region according
to `buffer-file-format'. Problem reported at:
- <http://sourceforge.jp/ticket/browse.php?group_id=2267&tid=32917>.
+ <https://sourceforge.jp/ticket/browse.php?group_id=2267&tid=32917>.
2014-01-14 Stefan Monnier <monnier@iro.umontreal.ca>
diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index c73a623cce9..338814fdda2 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -31,10 +31,16 @@ EXEEXT = @EXEEXT@
XARGS_LIMIT = @XARGS_LIMIT@
HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
+NATIVE_COMPILATION_AOT = @NATIVE_COMPILATION_AOT@
ifeq ($(HAVE_NATIVE_COMP),yes)
+# Environment variable to enable Ahead-Of-Time compilation.
ifndef NATIVE_FULL_AOT
NATIVE_SKIP_NONDUMP = 1
endif
+# Configured for Ahead-Of-Time compilation.
+ifeq ($(NATIVE_COMPILATION_AOT),yes)
+NATIVE_SKIP_NONDUMP = ""
+endif
endif
-include ${top_builddir}/src/verbose.mk
@@ -70,9 +76,7 @@ BYTE_COMPILE_FLAGS = \
--eval "(setq load-prefer-newer t byte-compile-warnings 'all)" \
$(BYTE_COMPILE_EXTRA_FLAGS)
# ... but we must prefer .elc files for those in the early bootstrap.
-# A larger `max-specpdl-size' is needed for emacs-lisp/comp.el.
-compile-first: BYTE_COMPILE_FLAGS = \
- --eval '(setq max-specpdl-size 5000)' $(BYTE_COMPILE_EXTRA_FLAGS)
+compile-first: BYTE_COMPILE_FLAGS = $(BYTE_COMPILE_EXTRA_FLAGS)
# Files to compile before others during a bootstrap. This is done to
# speed up the bootstrap process. They're ordered by size, so we use
@@ -306,16 +310,18 @@ endif
ifeq ($(HAVE_NATIVE_COMP),yes)
ifeq ($(ANCIENT),yes)
# The first compilation of compile-first, using an interpreted compiler:
-# The resulting .elc files get given a date of 1971-01-01 so that their
-# date stamp is earlier than the source files, causing these to be compiled
-# into native code at the second recursive invocation of this $(MAKE),
-# using these .elc's. This is faster than just compiling the native code
-# directly using the interpreted compile-first files. (Note: 1970-01-01
-# fails on some systems.)
+# The resulting .elc files get given a timestamp of the Unix epoch,
+# 1970-01-01, so that their timestamps are earlier than the source files,
+# causing these to be compiled into native code at the second recursive
+# invocation of this $(MAKE), using these .elc's. This is faster than just
+# compiling the native code directly using the interpreted compile-first
+# files. Note that the epoch date is hard-coded into Fload in src/lread.c
+# which uses it to avoid displaying certain messages which might be
+# irritating/misleading during a bootstrap.
.el.elc:
$(AM_V_ELC)$(emacs) $(BYTE_COMPILE_FLAGS) \
-l comp -f batch-byte-compile $<
- touch -t 197101010000 $@
+ TZ=UTC0 touch -t 197001010000 $@
else
.el.elc:
$(AM_V_ELC)$(emacs) $(BYTE_COMPILE_FLAGS) \
@@ -342,8 +348,8 @@ compile-first: $(COMPILE_FIRST)
.PHONY: compile-targets
# TARGETS is set dynamically in the recursive call from 'compile-main'.
-# Do not build comp.el unless necessary not to exceed max-specpdl-size and
-# max-lisp-eval-depth in normal builds.
+# Do not build comp.el unless necessary not to exceed max-lisp-eval-depth
+# in normal builds.
ifneq ($(HAVE_NATIVE_COMP),yes)
compile-targets: $(filter-out ./emacs-lisp/comp-cstr.elc,$(filter-out ./emacs-lisp/comp.elc,$(TARGETS)))
else
@@ -424,6 +430,12 @@ compile-always:
find $(lisp) -name '*.elc' $(FIND_DELETE)
$(MAKE) compile
+.PHONY: trampolines
+trampolines: compile
+ifeq ($(HAVE_NATIVE_COMP),yes)
+ $(emacs) -l comp -f comp-compile-all-trampolines
+endif
+
.PHONY: backup-compiled-files compile-after-backup
# Backup compiled Lisp files in elc.tar.gz. If that file already
diff --git a/lisp/abbrev.el b/lisp/abbrev.el
index 718938df0cb..a4f0196a789 100644
--- a/lisp/abbrev.el
+++ b/lisp/abbrev.el
@@ -1,7 +1,6 @@
;;; abbrev.el --- abbrev mode commands for Emacs -*- lexical-binding: t -*-
-;; Copyright (C) 1985-1987, 1992, 2001-2022 Free Software Foundation,
-;; Inc.
+;; Copyright (C) 1985-2022 Free Software Foundation, Inc.
;; Maintainer: emacs-devel@gnu.org
;; Keywords: abbrev convenience
@@ -1220,13 +1219,28 @@ SORTFUN is passed to `sort' to change the default ordering."
(sort entries (lambda (x y)
(funcall sortfun (nth 2 x) (nth 2 y)))))))
+(defface abbrev-table-name
+ '((t :inherit font-lock-function-name-face))
+ "Face used for displaying the abbrev table name in `edit-abbrev-mode'."
+ :version "29.1")
+
+(defvar edit-abbrevs-mode-font-lock-keywords
+ `((,(rx bol "("
+ ;; lisp-mode-symbol-regexp
+ (regexp "\\(?:\\sw\\|\\s_\\|\\\\.\\)+")
+ ")" eol)
+ 0 'abbrev-table-name)))
+
;; Keep it after define-abbrev-table, since define-derived-mode uses
;; define-abbrev-table.
(define-derived-mode edit-abbrevs-mode fundamental-mode "Edit-Abbrevs"
"Major mode for editing the list of abbrev definitions.
This mode is for editing abbrevs in a buffer prepared by `edit-abbrevs',
which see."
- :interactive nil)
+ :interactive nil
+ (setq-local font-lock-defaults
+ '(edit-abbrevs-mode-font-lock-keywords nil nil ((?_ . "w"))))
+ (setq font-lock-multiline nil))
(defun abbrev--possibly-save (query &optional arg)
;; Query mode.
diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el
index 736fb7d99d6..7a65777d323 100644
--- a/lisp/allout-widgets.el
+++ b/lisp/allout-widgets.el
@@ -312,7 +312,7 @@ enhancements, directly.")
(defvar-local allout-inhibit-body-modification-hook nil
"Override de-escaping of text-prefixes in item bodies during specific changes.
-This is used by `allout-buffer-modification-handler' to signal such changes
+This is used by `allout-body-modification-handler' to signal such changes
to `allout-body-modification-handler', and is always reset by
`allout-post-command-business'.")
;;;_ = allout-widgets-icons-cache
@@ -2180,7 +2180,7 @@ Operation is inhibited by `allout-inhibit-body-modification-handler'."
;; `allout-before-modification-handler' and
;; `allout-inhibit-body-modification-handler'.
;;
-;; Adds the overlay to the `allout-unresolved-body-mod-workhash' during
+;; Adds the overlay to the `allout-unresolved-body-mod-workroster' during
;; before-change operation, and removes from that list during after-change
;; operation.
(cond (allout-inhibit-body-modification-hook nil)))
diff --git a/lisp/ansi-osc.el b/lisp/ansi-osc.el
new file mode 100644
index 00000000000..34154998cdf
--- /dev/null
+++ b/lisp/ansi-osc.el
@@ -0,0 +1,203 @@
+;;; ansi-osc.el --- Support for OSC escape sequences -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Augusto Stoffel <arstoffel@gmail.com>
+;; Matthias Meulien <orontee@gmail.com>
+;; Maintainer: emacs-devel@gnu.org
+;; Keywords: processes, terminals, services
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Interpretation of OSC (Operating System Commands) escape sequences.
+;; Handlers for OSC 2, 7 and 8 (for window title, current directory
+;; and hyperlinks respectively) are provided.
+
+;; The function `ansi-osc-compilation-filter' can be added to
+;; `compilation-filter-hook' to collect OSC sequences in compilation
+;; buffers. The variable `ansi-osc-for-compilation-buffer' tells what
+;; to do with collected sequences.
+
+;;; Code:
+
+(defconst ansi-osc-control-seq-regexp
+ ;; See ECMA 48, section 8.3.89 "OSC - OPERATING SYSTEM COMMAND".
+ "\e\\][\x08-\x0D]*[\x20-\x7E]*\\(\a\\|\e\\\\\\)"
+ "Regexp matching an OSC control sequence.")
+
+(defun ansi-osc-filter-region (begin end)
+ "Filter out all OSC control sequences from region between BEGIN and END."
+ (save-excursion
+ (goto-char begin)
+ ;; Delete escape sequences.
+ (while (re-search-forward ansi-osc-control-seq-regexp end t)
+ (delete-region (match-beginning 0) (match-end 0)))))
+
+(defvar-local ansi-osc-handlers '(("2" . ansi-osc-window-title-handler)
+ ("7" . ansi-osc-directory-tracker)
+ ("8" . ansi-osc-hyperlink-handler))
+ "Alist of handlers for OSC escape sequences.
+See `ansi-osc-apply-on-region' for details.")
+
+(defvar-local ansi-osc--marker nil)
+;; The function `ansi-osc-apply-on-region' can set `ansi-osc--marker'
+;; to the start position of an escape sequence without termination.
+
+(defun ansi-osc-apply-on-region (begin end)
+ "Interpret OSC escape sequences in region between BEGIN and END.
+This function searches for escape sequences of the forms
+
+ ESC ] command ; text BEL
+ ESC ] command ; text ESC \\
+
+Every occurrence of such escape sequences is removed from the
+buffer. Then, if `command' is a key in the alist that is the
+value of the local variable `ansi-osc-handlers', that key's
+value, which should be a function, is called with `command' and
+`text' as arguments, with point where the escape sequence was
+located."
+ (save-excursion
+ (goto-char (or ansi-osc--marker begin))
+ (when (eq (char-before) ?\e) (backward-char))
+ (while (re-search-forward "\e]" end t)
+ (let ((pos0 (match-beginning 0))
+ (code (and (re-search-forward "\\=\\([0-9A-Za-z]*\\);" end t)
+ (match-string 1)))
+ (pos1 (point)))
+ (if (re-search-forward "\a\\|\e\\\\" end t)
+ (let ((text (buffer-substring-no-properties
+ pos1 (match-beginning 0))))
+ (setq ansi-osc--marker nil)
+ (delete-region pos0 (point))
+ (when-let ((fun (cdr (assoc-string code ansi-osc-handlers))))
+ (funcall fun code text)))
+ (put-text-property pos0 end 'invisible t)
+ (setq ansi-osc--marker (copy-marker pos0)))))))
+
+;; Window title handling (OSC 2)
+
+(defvar-local ansi-osc-window-title nil)
+(defun ansi-osc-window-title-handler (_ text)
+ "Set value of `ansi-osc-window-title' from an OSC 2 escape sequence.
+The variable `ansi-osc-window-title' can then be referenced in
+`frame-title-format' to dynamically set the frame title.
+
+This function is intended to be included as an element of the
+list that is the value of `ansi-osc-handlers'."
+ (setq ansi-osc-window-title text))
+
+;; Current directory tracking (OSC 7)
+
+(declare-function url-host "url/url-parse.el")
+(declare-function url-type "url/url-parse.el")
+(declare-function url-filename "url/url-parse.el")
+(defun ansi-osc-directory-tracker (_ text)
+ "Update `default-directory' from OSC 7 escape sequences.
+
+This function is intended to be included as an element of the
+the list that is the value of `ansi-osc-handlers'. You should arrange
+for your shell to print the appropriate escape sequence at each prompt,
+such as with the following command:
+
+ printf \"\\e]7;file://%s%s\\e\\\\\" \"$HOSTNAME\" \"$PWD\"
+
+This functionality serves as an alternative to `dirtrack-mode'
+and `shell-dirtrack-mode'."
+ (let ((url (url-generic-parse-url text)))
+ (when (and (string= (url-type url) "file")
+ (or (null (url-host url))
+ (string= (url-host url) (system-name))))
+ (ignore-errors
+ (cd-absolute (url-unhex-string (url-filename url)))))))
+
+;; Hyperlink handling (OSC 8)
+
+(defvar ansi-osc-hyperlink-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-c\r" 'browse-url-button-open)
+ (define-key map [mouse-2] 'browse-url-button-open)
+ (define-key map [follow-link] 'mouse-face)
+ map)
+ "Keymap used by OSC 8 hyperlink buttons.")
+
+(define-button-type 'ansi-osc-hyperlink
+ 'keymap ansi-osc-hyperlink-map
+ 'help-echo (lambda (_ buffer pos)
+ (when-let ((url (get-text-property pos 'browse-url-data buffer)))
+ (format "mouse-2, C-c RET: Open %s" url))))
+
+(defvar-local ansi-osc-hyperlink--state nil)
+
+(defun ansi-osc-hyperlink-handler (_ text)
+ "Create a hyperlink from an OSC 8 escape sequence.
+This function is intended to be included as an elemnt of the list
+that is the value of `ansi-osc-handlers'."
+ (when ansi-osc-hyperlink--state
+ (let ((start (car ansi-osc-hyperlink--state))
+ (url (cdr ansi-osc-hyperlink--state)))
+ (make-text-button start (point)
+ 'type 'ansi-osc-hyperlink
+ 'browse-url-data url)))
+ (setq ansi-osc-hyperlink--state
+ (and (string-match ";\\(.+\\)" text)
+ (cons (point-marker) (match-string-no-properties 1 text)))))
+
+(defgroup ansi-osc nil
+ "Interpretation of OSC escape sequences.
+Handlers for OSC 2, 7 and 8 (for window title, current directory
+and hyperlinks respectively) are provided. OSC (Operating System
+Commands) control sequences are defined in section 8.3.89 of the
+ECMA-48 standard is freely available at
+<URL:https://www.ecma-international.org/publications/standards/Ecma-048.htm>
+as a PDF file."
+ :version "29.1"
+ :group 'processes)
+
+(defcustom ansi-osc-for-compilation-buffer 'filter
+ "What to do with OSC escape sequences in compilation output.
+
+If nil, do nothing.
+
+If the symbol `filter', then filter out all OSC control sequences.
+
+If any other non-nil value, then collect OSC control sequences
+and call the appropriate handlers as described in `ansi-osc-handlers'.
+
+In order for this to have any effect, `ansi-osc-compilation-filter'
+must be in `compilation-filter-hook'."
+ :type '(choice (const :tag "Do nothing" nil)
+ (const :tag "Filter out OSC" filter)
+ (other :tag "Translate OSC" t))
+ :group 'ansi-osc
+ :version "29.1")
+
+(defvar compilation-filter-start)
+
+;;;###autoload
+(defun ansi-osc-compilation-filter ()
+ "Maybe collect OSC control sequences.
+This function depends on the variable `ansi-osc-for-compilation-buffer',
+and is meant to be used in `compilation-filter-hook'."
+ (let ((inhibit-read-only t))
+ (pcase ansi-osc-for-compilation-buffer
+ ('nil nil)
+ ('filter
+ (ansi-osc-filter-region compilation-filter-start (point)))
+ (_
+ (ansi-osc-apply-on-region compilation-filter-start (point))))))
+
+(provide 'ansi-osc)
+;;; ansi-osc.el ends here
diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el
index 86e0b48a79d..0955e2ed07e 100644
--- a/lisp/auth-source-pass.el
+++ b/lisp/auth-source-pass.el
@@ -319,6 +319,16 @@ then NAME & USER, then NAME & PORT, then just NAME."
(list
(format "%s" name)))))
+(defun auth-source-pass-file-name-p (file)
+ "Say whether FILE is used by `auth-source-pass'."
+ (and (stringp file) (stringp auth-source-pass-filename)
+ (string-equal
+ (expand-file-name file) (expand-file-name auth-source-pass-filename))))
+
+(with-eval-after-load 'bookmark
+ (add-hook 'bookmark-inhibit-context-functions
+ #'auth-source-pass-file-name-p))
+
(provide 'auth-source-pass)
;;; auth-source-pass.el ends here
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index c79e5b81f76..feefd391a87 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -522,6 +522,21 @@ parameters."
;; (mapcar #'auth-source-backend-parse auth-sources)
+(defun auth-source-file-name-p (file)
+ "Say whether FILE is used by `auth-sources'."
+ (let* ((backends (mapcar #'auth-source-backend-parse auth-sources))
+ (files
+ (mapcar (lambda (x)
+ (when (member (slot-value x 'type) '(json netrc plstore))
+ (slot-value x 'source)))
+ backends)))
+ (member (expand-file-name file)
+ (mapcar #'expand-file-name (remq nil files)))))
+
+(with-eval-after-load 'bookmark
+ (add-hook 'bookmark-inhibit-context-functions
+ #'auth-source-file-name-p))
+
(cl-defun auth-source-search (&rest spec
&key max require create delete
&allow-other-keys)
diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el
index 29d10bc6295..51d939151ce 100644
--- a/lisp/autoinsert.el
+++ b/lisp/autoinsert.el
@@ -1,7 +1,6 @@
;;; autoinsert.el --- automatic mode-dependent insertion of text into new files -*- lexical-binding: t -*-
-;; Copyright (C) 1985-1987, 1994-1995, 1998, 2000-2022 Free Software
-;; Foundation, Inc.
+;; Copyright (C) 1985-2022 Free Software Foundation, Inc.
;; Author: Charlie Martin <crm@cs.duke.edu>
;; Adapted-By: Daniel Pfeiffer <occitan@esperanto.org>
@@ -25,27 +24,27 @@
;;; Commentary:
-;; The following defines an association list for text to be
-;; automatically inserted when a new file is created, and a function
-;; which automatically inserts these files; the idea is to insert
-;; default text much as the mode is automatically set using
-;; auto-mode-alist.
+;; The following defines an association list for text to be
+;; automatically inserted when a new file is created, and a function
+;; which automatically inserts these files; the idea is to insert
+;; default text much as the mode is automatically set using
+;; auto-mode-alist.
+;;
+;; To use, add this to your Init file:
;;
-;; To use:
;; (auto-insert-mode t)
-;; setq auto-insert-directory to an appropriate slash-terminated value
+;; (setq auto-insert-directory "~/some-dir")
;;
-;; You can also customize the variable `auto-insert-mode' to load the
-;; package. Alternatively, add the following to your init file:
-;; (auto-insert-mode 1)
+;; You can also customize the variable `auto-insert-mode' to load the
+;; package.
;;
-;; Author: Charlie Martin
-;; Department of Computer Science and
-;; National Biomedical Simulation Resource
-;; Box 3709
-;; Duke University Medical Center
-;; Durham, NC 27710
-;; (crm@cs.duke.edu,mcnc!duke!crm)
+;; Author: Charlie Martin
+;; Department of Computer Science and
+;; National Biomedical Simulation Resource
+;; Box 3709
+;; Duke University Medical Center
+;; Durham, NC 27710
+;; (crm@cs.duke.edu,mcnc!duke!crm)
;;; Code:
@@ -169,7 +168,7 @@ If this contains a %s, that will be replaced by the matching rule."
(".dir-locals.el"
nil
- ";;; Directory Local Variables\n"
+ ";;; Directory Local Variables -*- no-byte-compile: t; -*-\n"
";;; For more information see (info \"(emacs) Directory Variables\")\n\n"
"(("
'(setq v1 (let (modes)
@@ -348,9 +347,7 @@ described above, e.g. [\"header.insert\" date-and-author-update]."
;; Establish a default value for auto-insert-directory
(defcustom auto-insert-directory "~/insert/"
- "Directory from which auto-inserted files are taken.
-The value must be an absolute directory name;
-thus, on a GNU or Unix system, it must end in a slash."
+ "Directory from which auto-inserted files are taken."
:type 'directory)
diff --git a/lisp/autorevert.el b/lisp/autorevert.el
index 872a896689c..576659675b5 100644
--- a/lisp/autorevert.el
+++ b/lisp/autorevert.el
@@ -677,7 +677,7 @@ will use an up-to-date value of `auto-revert-interval'."
;;
;; We do this by reverting immediately in response to the first in a
;; flurry of notifications. Any notifications during the following
-;; `auto-revert-lockout-interval' seconds are noted but not acted upon
+;; `auto-revert--lockout-interval' seconds are noted but not acted upon
;; until the end of that interval.
(defconst auto-revert--lockout-interval 2.5
diff --git a/lisp/battery.el b/lisp/battery.el
index 72b3dfdae7c..8de80109c6c 100644
--- a/lisp/battery.el
+++ b/lisp/battery.el
@@ -914,6 +914,15 @@ The following %-sequences are provided:
;;; `apm' interface for BSD.
+;; This function is a wrapper on `call-process' that return the
+;; standard output in a string. We are using it instead
+;; `shell-command-to-string' because this last one is trying to run
+;; PROGRAM on the remote host if the buffer is remote.
+(defun battery--call-process-to-string (program &rest args)
+ (with-output-to-string
+ (with-current-buffer standard-output
+ (apply #'call-process program nil t nil args))))
+
(defun battery-bsd-apm ()
"Get APM status information from BSD apm binary.
The following %-sequences are provided:
@@ -929,13 +938,14 @@ The following %-sequences are provided:
%t Remaining time (to charge or discharge) in the form `h:min'"
(let* ((os-name (car (split-string
;; FIXME: Can't we use something like `system-type'?
- (shell-command-to-string "/usr/bin/uname"))))
+ (battery--call-process-to-string "uname"))))
(apm-flag (pcase os-name
("OpenBSD" "mP")
("FreeBSD" "st")
(_ "ms")))
- (apm-cmd (concat "/usr/sbin/apm -abl" apm-flag))
- (apm-output (split-string (shell-command-to-string apm-cmd)))
+ (apm-args (concat "-abl" apm-flag))
+ (apm-output (split-string
+ (battery--call-process-to-string "apm" apm-args)))
(indices (pcase os-name
;; FreeBSD's manpage documents that multiple
;; outputs are ordered by "the order in which
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index 8dfc16bf9fa..b57ad12986d 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -592,9 +592,26 @@ NAME is a suggested name for the constructed bookmark. It can be nil
in which case a default heuristic will be used. The function can also
equivalently just return ALIST without NAME.")
+(defcustom bookmark-inhibit-context-functions nil
+ "List of functions to call before making a bookmark record.
+The functions take `buffer-file-name' as argument. If any of
+these functions returns non-nil, the bookmark does not record
+context strings from the current buffer."
+ :type 'hook
+ :version "29.1")
+
(defun bookmark-make-record ()
"Return a new bookmark record (NAME . ALIST) for the current location."
- (let ((record (funcall bookmark-make-record-function)))
+ (let* ((bookmark-search-size
+ ;; If we're in a buffer that's visiting an encrypted file,
+ ;; don't include any context in the bookmark file, because
+ ;; that would leak (possibly secret) data.
+ (if (and buffer-file-name
+ (run-hook-with-args-until-success
+ 'bookmark-inhibit-context-functions buffer-file-name))
+ 0
+ bookmark-search-size))
+ (record (funcall bookmark-make-record-function)))
;; Set up default name if the function does not provide one.
(unless (stringp (car record))
(if (car record) (push nil record))
@@ -1441,7 +1458,7 @@ name."
(let ((final-new-name
(or new-name ; use second arg, if non-nil
(read-from-minibuffer
- "New name: "
+ (format-prompt "Rename \"%s\" to" nil old-name)
nil
(define-keymap
:parent minibuffer-local-map
diff --git a/lisp/calc/calc-embed.el b/lisp/calc/calc-embed.el
index bb427ef86e6..4a9ff256f9f 100644
--- a/lisp/calc/calc-embed.el
+++ b/lisp/calc/calc-embed.el
@@ -207,9 +207,8 @@
;; The following is to take care of any minor modes which override
;; a Calc command.
-(defvar calc-override-minor-modes-map
- (make-sparse-keymap)
- "A list of keybindings that might be overwritten by minor modes.")
+(defvar-keymap calc-override-minor-modes-map
+ :doc "A list of keybindings that might be overwritten by minor modes.")
;; Add any keys that might be overwritten here.
(define-key calc-override-minor-modes-map "`" 'calc-edit)
diff --git a/lisp/calc/calc-stuff.el b/lisp/calc/calc-stuff.el
index 0e8ea42bedc..758b9201843 100644
--- a/lisp/calc/calc-stuff.el
+++ b/lisp/calc/calc-stuff.el
@@ -52,18 +52,14 @@ With a prefix, push that prefix as a number onto the stack."
(calc-less-recursion-depth n)
(let ((n (if n (prefix-numeric-value n) 2)))
(if (> n 1)
- (setq max-specpdl-size (* max-specpdl-size n)
- max-lisp-eval-depth (* max-lisp-eval-depth n))))
+ (setq max-lisp-eval-depth (* max-lisp-eval-depth n))))
(message "max-lisp-eval-depth is now %d" max-lisp-eval-depth))))
(defun calc-less-recursion-depth (n)
(interactive "P")
(let ((n (if n (prefix-numeric-value n) 2)))
(if (> n 1)
- (setq max-specpdl-size
- (max (/ max-specpdl-size n) 600)
- max-lisp-eval-depth
- (max (/ max-lisp-eval-depth n) 200))))
+ (setq max-lisp-eval-depth (max (/ max-lisp-eval-depth n) 200))))
(message "max-lisp-eval-depth is now %d" max-lisp-eval-depth))
diff --git a/lisp/calc/calc-yank.el b/lisp/calc/calc-yank.el
index 504ba5b40d1..35014e022be 100644
--- a/lisp/calc/calc-yank.el
+++ b/lisp/calc/calc-yank.el
@@ -668,13 +668,11 @@ Interactively, reads the register using `register-read-with-preview'."
(backward-char 1)
(calc-set-command-flag 'do-edit))
-(defvar calc-edit-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\n" #'calc-edit-finish)
- (define-key map "\r" #'calc-edit-return)
- (define-key map "\C-c\C-c" #'calc-edit-finish)
- map)
- "Keymap for use by the `calc-edit' command.")
+(defvar-keymap calc-edit-mode-map
+ :doc "Keymap for use by the `calc-edit' command."
+ "C-j" #'calc-edit-finish
+ "RET" #'calc-edit-return
+ "C-c C-c" #'calc-edit-finish)
(defvar calc-original-buffer nil)
(defvar calc-return-buffer nil)
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 6c21430b1b3..6ea8a4202fc 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -1162,7 +1162,7 @@ Used by `calc-user-invocation'.")
;;;; (Autoloads here)
-(load "calc-loaddefs.el" nil t)
+(load "calc-loaddefs" nil t)
;;;###autoload (define-key ctl-x-map "*" 'calc-dispatch)
@@ -1373,10 +1373,8 @@ Notations: 3.14e6 3.14 * 10^6
(calc-check-defines))
(setplist 'calc-define nil)))))
-(defvar calc-trail-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map calc-mode-map)
- map))
+(defvar-keymap calc-trail-mode-map
+ :parent calc-mode-map)
(defun calc--header-line (long short width &optional fudge)
"Return a Calc header line appropriate for the buffer WIDTH.
@@ -1627,8 +1625,7 @@ See calc-keypad for details."
(error
(if (and (eq (car err) 'error)
(stringp (nth 1 err))
- (string-match "max-specpdl-size\\|max-lisp-eval-depth"
- (nth 1 err)))
+ (string-search "max-lisp-eval-depth" (nth 1 err)))
(error (substitute-command-keys
"Computation got stuck or ran too long. Type \\`M' to increase the limit"))
(setq calc-aborted-prefix nil)
diff --git a/lisp/calendar/cal-move.el b/lisp/calendar/cal-move.el
index 4febad53fc5..211e0f1e62d 100644
--- a/lisp/calendar/cal-move.el
+++ b/lisp/calendar/cal-move.el
@@ -384,7 +384,8 @@ Moves forward if ARG is negative."
;;;###cal-autoload
(defun calendar-goto-day-of-year (year day &optional noecho)
"Move cursor to YEAR, DAY number; echo DAY/YEAR unless NOECHO is non-nil.
-Negative DAY counts backward from end of year."
+Negative DAY counts backward from end of year.
+Interactively, prompt for YEAR and DAY number."
(interactive
(let* ((year (calendar-read-sexp
"Year (>0)"
@@ -394,7 +395,7 @@ Negative DAY counts backward from end of year."
(day (calendar-read-sexp
"Day number (+/- 1-%d)"
(lambda (x) (and (<= 1 (abs x)) (<= (abs x) last)))
- nil
+ (calendar-day-number (calendar-current-date))
last)))
(list year day)))
(calendar-goto-date
diff --git a/lisp/cedet/ede/autoconf-edit.el b/lisp/cedet/ede/autoconf-edit.el
index 78edea1da8d..8458820bdd0 100644
--- a/lisp/cedet/ede/autoconf-edit.el
+++ b/lisp/cedet/ede/autoconf-edit.el
@@ -34,8 +34,7 @@
"Initialize a new configure.ac in ROOTDIR for PROGRAM using TESTFILE.
ROOTDIR is the root directory of a given autoconf controlled project.
PROGRAM is the program to be configured.
-TESTFILE is the file used with AC_INIT.
-Configure the initial configure script using `autoconf-new-automake-string'."
+TESTFILE is the file used with AC_INIT."
(interactive "DRoot Dir: \nsProgram: \nsTest File: ")
(require 'ede/srecode)
(if (bufferp rootdir)
diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el
index 9941f2a0cb7..5b0df013a3c 100644
--- a/lisp/cedet/pulse.el
+++ b/lisp/cedet/pulse.el
@@ -47,7 +47,7 @@
;; The original pulse code was written for semantic tag highlighting.
;; It has been extracted, and adapted for general purpose pulsing.
;;
-;; Pulse is a part of CEDET. http://cedet.sf.net
+;; Pulse is a part of CEDET. https://cedet.sourceforge.net
(require 'color)
@@ -202,12 +202,8 @@ If POINT is nil or missing, the current point is used instead.
Optional argument FACE specifies the face to do the highlighting."
(save-excursion
(goto-char (or point (point)))
- (let ((start (line-beginning-position))
- (end (save-excursion
- (end-of-line)
- (when (not (eobp))
- (forward-char 1))
- (point))))
+ (let ((start (progn (vertical-motion 0) (point)))
+ (end (progn (vertical-motion 1) (point))))
(pulse-momentary-highlight-region start end face))))
;;;###autoload
diff --git a/lisp/cedet/semantic/ede-grammar.el b/lisp/cedet/semantic/ede-grammar.el
index ff9f991ff4a..40ff8fc86d3 100644
--- a/lisp/cedet/semantic/ede-grammar.el
+++ b/lisp/cedet/semantic/ede-grammar.el
@@ -177,10 +177,9 @@ Lays claim to all -by.el, and -wy.el files."
(cl-defmethod ede-proj-makefile-insert-rules :after ((this semantic-ede-proj-target-grammar))
"Insert rules needed by THIS target.
-This raises `max-specpdl-size' and `max-lisp-eval-depth', which can be
-needed for the compilation of the resulting parsers."
- (insert (format "%s: EMACSFLAGS+= --eval '(setq max-specpdl-size 1500 \
-max-lisp-eval-depth 700)'\n"
+This raises `max-lisp-eval-depth', which can be needed for the compilation
+of the resulting parsers."
+ (insert (format "%s: EMACSFLAGS+= --eval '(setq max-lisp-eval-depth 700)'\n"
(oref this name))))
(cl-defmethod ede-proj-makefile-insert-dist-dependencies ((this semantic-ede-proj-target-grammar))
diff --git a/lisp/cedet/semantic/edit.el b/lisp/cedet/semantic/edit.el
index 7cb6768f7e1..4efc283520f 100644
--- a/lisp/cedet/semantic/edit.el
+++ b/lisp/cedet/semantic/edit.el
@@ -128,11 +128,9 @@ If nil, errors are still displayed, but informative messages are not."
"Provide a mechanism for semantic tag management.
Argument START, END, and LENGTH specify the bounds of the change."
(setq semantic-unmatched-syntax-cache-check t)
- (let ((inhibit-point-motion-hooks t)
- )
- (save-match-data
- (run-hook-with-args 'semantic-change-functions start end length)
- )))
+ (save-match-data
+ (run-hook-with-args 'semantic-change-functions start end length)
+ ))
(defun semantic-changes-in-region (start end &optional buffer)
"Find change overlays which exist in whole or in part between START and END.
diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el
index d42022e0423..8ba0e346fff 100644
--- a/lisp/cedet/semantic/grammar.el
+++ b/lisp/cedet/semantic/grammar.el
@@ -1009,7 +1009,6 @@ Return non-nil if there were no errors, nil if errors."
packagename (byte-compile-dest-file packagename))
(let (;; Some complex grammar table expressions need a few
;; more resources than the default.
- (max-specpdl-size (max 3000 max-specpdl-size))
(max-lisp-eval-depth (max 1000 max-lisp-eval-depth))
)
;; byte compile the resultant file
@@ -1148,9 +1147,9 @@ END is the limit of the search."
(defvar semantic-grammar-mode-keywords-1
`(("\\(\\<%%\\>\\|\\<%[{}]\\)"
- 0 font-lock-reference-face)
+ 0 font-lock-constant-face)
("\\(%\\)\\(\\(\\sw\\|\\s_\\)+\\)"
- (1 font-lock-reference-face)
+ (1 font-lock-constant-face)
(2 font-lock-keyword-face))
("\\<error\\>"
0 (unless (semantic-grammar-in-lisp-p) 'bold))
@@ -1167,7 +1166,8 @@ END is the limit of the search."
(,semantic-grammar-lex-c-char-re
0 ,(if (boundp 'font-lock-constant-face)
'font-lock-constant-face
- 'font-lock-string-face) t)
+ 'font-lock-string-face)
+ t)
;; Must highlight :keyword here, because ':' is a punctuation in
;; grammar mode!
("[\r\n\t ]+:\\sw+\\>"
diff --git a/lisp/cedet/semantic/mru-bookmark.el b/lisp/cedet/semantic/mru-bookmark.el
index 9dee0415a33..c3f59a3358f 100644
--- a/lisp/cedet/semantic/mru-bookmark.el
+++ b/lisp/cedet/semantic/mru-bookmark.el
@@ -264,11 +264,9 @@ been edited, and you can re-visit them with \\[semantic-mrub-switch-tags]."
:group 'semantic
:type 'hook)
-(defvar semantic-mru-bookmark-mode-map
- (let ((km (make-sparse-keymap)))
- (define-key km "\C-xB" #'semantic-mrub-switch-tags)
- km)
- "Keymap for mru-bookmark minor mode.")
+(defvar-keymap semantic-mru-bookmark-mode-map
+ :doc "Keymap for mru-bookmark minor mode."
+ "C-x B" #'semantic-mrub-switch-tags)
(define-minor-mode semantic-mru-bookmark-mode
"Minor mode for tracking tag-based bookmarks automatically.
diff --git a/lisp/cedet/semantic/util-modes.el b/lisp/cedet/semantic/util-modes.el
index 33fed9191e1..96d1de5a26c 100644
--- a/lisp/cedet/semantic/util-modes.el
+++ b/lisp/cedet/semantic/util-modes.el
@@ -196,10 +196,8 @@ Argument OVERLAY is the overlay created to mark the change.
This function will set the face property on this overlay."
(overlay-put overlay 'face 'semantic-highlight-edits-face))
-(defvar semantic-highlight-edits-mode-map
- (let ((km (make-sparse-keymap)))
- km)
- "Keymap for highlight-edits minor mode.")
+(defvar-keymap semantic-highlight-edits-mode-map
+ :doc "Keymap for highlight-edits minor mode.")
;;;###autoload
(define-minor-mode semantic-highlight-edits-mode
@@ -343,11 +341,9 @@ Do not search past BOUND if non-nil."
(setq ol (cdr ol))))))
ol)))
-(defvar semantic-show-unmatched-syntax-mode-map
- (let ((km (make-sparse-keymap)))
- (define-key km "\C-c,`" #'semantic-show-unmatched-syntax-next)
- km)
- "Keymap for command `semantic-show-unmatched-syntax-mode'.")
+(defvar-keymap semantic-show-unmatched-syntax-mode-map
+ :doc "Keymap for command `semantic-show-unmatched-syntax-mode'."
+ "C-c , `" #'semantic-show-unmatched-syntax-next)
;;;###autoload
(define-minor-mode semantic-show-unmatched-syntax-mode
@@ -417,10 +413,8 @@ non-nil if the minor mode is enabled.
:group 'semantic
:type 'hook)
-(defvar semantic-show-parser-state-mode-map
- (let ((km (make-sparse-keymap)))
- km)
- "Keymap for show-parser-state minor mode.")
+(defvar-keymap semantic-show-parser-state-mode-map
+ :doc "Keymap for show-parser-state minor mode.")
;;;###autoload
(define-minor-mode semantic-show-parser-state-mode
@@ -553,11 +547,9 @@ to indicate a parse in progress."
:group 'semantic
:type 'hook)
-(defvar semantic-stickyfunc-mode-map
- (let ((km (make-sparse-keymap)))
- (define-key km [ header-line down-mouse-1 ] #'semantic-stickyfunc-menu)
- km)
- "Keymap for stickyfunc minor mode.")
+(defvar-keymap semantic-stickyfunc-mode-map
+ :doc "Keymap for stickyfunc minor mode."
+ "<header-line> <down-mouse-1>" #'semantic-stickyfunc-menu)
(defvar semantic-stickyfunc-popup-menu nil
"Menu used if the user clicks on the header line used by stickyfunc mode.")
@@ -824,11 +816,9 @@ Argument EVENT describes the event that caused this function to be called."
:group 'semantic
:type 'hook)
-(defvar semantic-highlight-func-mode-map
- (let ((km (make-sparse-keymap)))
- (define-key km [mouse-3] #'semantic-highlight-func-menu)
- km)
- "Keymap for highlight-func minor mode.")
+(defvar-keymap semantic-highlight-func-mode-map
+ :doc "Keymap for highlight-func minor mode."
+ "<mouse-3>" #'semantic-highlight-func-menu)
(defvar semantic-highlight-func-popup-menu nil
"Menu used if the user clicks on the header line.
diff --git a/lisp/cedet/srecode/fields.el b/lisp/cedet/srecode/fields.el
index 2fc79d01a75..67ee82c73e0 100644
--- a/lisp/cedet/srecode/fields.el
+++ b/lisp/cedet/srecode/fields.el
@@ -334,9 +334,7 @@ START and END are the bounds of the change.
PRE-LEN is used in the after mode for the length of the changed text."
(when (and after (not undo-in-progress))
(let* ((field (overlay-get ol 'srecode))
- (inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t)
- )
+ (inhibit-modification-hooks t))
;; Sometimes a field is deleted, but we might still get a stray
;; event. Let's just ignore those events.
(when (slot-boundp field 'overlay)
diff --git a/lisp/cedet/srecode/insert.el b/lisp/cedet/srecode/insert.el
index db17b7f23f8..f8cfe2a733e 100644
--- a/lisp/cedet/srecode/insert.el
+++ b/lisp/cedet/srecode/insert.el
@@ -125,9 +125,7 @@ has set everything up already."
;; I tried `combine-after-change-calls', but it did not have
;; the effect I wanted.
(let ((start (point)))
- (let ((inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t)
- )
+ (let ((inhibit-modification-hooks t))
(srecode--insert-into-buffer template dictionary)
)
;; Now call those after change functions.
diff --git a/lisp/cedet/srecode/srt-mode.el b/lisp/cedet/srecode/srt-mode.el
index 56b482e1001..cc0983f9f9d 100644
--- a/lisp/cedet/srecode/srt-mode.el
+++ b/lisp/cedet/srecode/srt-mode.el
@@ -179,13 +179,11 @@ Don't scan past LIMIT."
Once the escape_start, and escape_end sequences are known, then
we can tell font lock about them.")
-(defvar srecode-template-mode-map
- (let ((km (make-sparse-keymap)))
- (define-key km "\C-c\C-c" #'srecode-compile-templates)
- (define-key km "\C-c\C-m" #'srecode-macro-help)
- (define-key km "/" #'srecode-self-insert-complete-end-macro)
- km)
- "Keymap used in srecode mode.")
+(defvar-keymap srecode-template-mode-map
+ :doc "Keymap used in srecode mode."
+ "C-c C-c" #'srecode-compile-templates
+ "C-c C-m" #'srecode-macro-help
+ "/" #'srecode-self-insert-complete-end-macro)
;;;###autoload
(define-derived-mode srecode-template-mode fundamental-mode "SRecode"
diff --git a/lisp/comint.el b/lisp/comint.el
index 696dac3d12b..07ced8d321a 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -103,6 +103,7 @@
(require 'ring)
(require 'ansi-color)
+(require 'ansi-osc)
(require 'regexp-opt) ;For regexp-opt-charset.
(eval-when-compile (require 'subr-x))
@@ -1944,7 +1945,7 @@ Similarly for Soar, Scheme, etc."
(when comint-highlight-input
(add-text-properties beg end
'( font-lock-face comint-highlight-input
- comint--fl-inhibit-fontification t
+ comint--fontify-input-inhibit-fontification t
front-sticky t )))
(unless comint-use-prompt-regexp
;; Give old user input a field property of `input', to
@@ -2146,6 +2147,12 @@ Make backspaces delete the previous character."
(goto-char (process-mark process))
(set-marker comint-last-output-start (point))
+ ;; Before we call `comint--mark-as-output' later,
+ ;; redisplay can be called. We mark the inserted text as
+ ;; output early, to prevent redisplay from fontifying it
+ ;; as input in case of `comint-fontify-input-mode'.
+ (put-text-property 0 (length string) 'field 'output string)
+
;; insert-before-markers is a bad thing. XXX
;; Luckily we don't have to use it any more, we use
;; window-point-insertion-type instead.
@@ -3914,12 +3921,12 @@ REGEXP-GROUP is the regular expression group in REGEXP to use."
;; to `comint-osc-handlers' allows a customized treatment of further
;; sequences.
-(defvar-local comint-osc-handlers '(("7" . comint-osc-directory-tracker)
- ("8" . comint-osc-hyperlink-handler))
- "Alist of handlers for OSC escape sequences.
-See `comint-osc-process-output' for details.")
-
-(defvar-local comint-osc--marker nil)
+;; Aliases defined for reverse compatibility
+(defvaralias 'comint-osc-handlers 'ansi-osc-handlers)
+(defalias 'comint-osc-directory-tracker 'ansi-osc-directory-tracker)
+(defalias 'comint-osc-hyperlink-handler 'ansi-osc-hyperlink-handler)
+(defalias 'comint-osc-hyperlink 'ansi-osc-hyperlink)
+(defvaralias 'comint-osc-hyperlink-map 'ansi-osc-hyperlink-map)
(defun comint-osc-process-output (_)
"Interpret OSC escape sequences in comint output.
@@ -3935,81 +3942,10 @@ removed from the buffer. Then, if `command' is a key of the
`comint-osc-handlers' alist, the corresponding value, which
should be a function, is called with `command' and `text' as
arguments, with point where the escape sequence was located."
- (let ((bound (process-mark (get-buffer-process (current-buffer)))))
- (save-excursion
- ;; Start one char before last output to catch a possibly stray ESC
- (goto-char (or comint-osc--marker (1- comint-last-output-start)))
- (when (eq (char-before) ?\e) (backward-char))
- (while (re-search-forward "\e]" bound t)
- (let ((pos0 (match-beginning 0))
- (code (and (re-search-forward "\\=\\([0-9A-Za-z]*\\);" bound t)
- (match-string 1)))
- (pos1 (point)))
- (if (re-search-forward "\a\\|\e\\\\" bound t)
- (let ((text (buffer-substring-no-properties
- pos1 (match-beginning 0))))
- (setq comint-osc--marker nil)
- (delete-region pos0 (point))
- (when-let ((fun (cdr (assoc-string code comint-osc-handlers))))
- (funcall fun code text)))
- (put-text-property pos0 bound 'invisible t)
- (setq comint-osc--marker (copy-marker pos0))))))))
-
-;; Current directory tracking (OSC 7)
-
-(declare-function url-host "url/url-parse.el")
-(declare-function url-type "url/url-parse.el")
-(declare-function url-filename "url/url-parse.el")
-(defun comint-osc-directory-tracker (_ text)
- "Update `default-directory' from OSC 7 escape sequences.
-
-This function is intended to be included as an entry of
-`comint-osc-handlers'. You should moreover arrange for your
-shell to print the appropriate escape sequence at each prompt,
-say with the following command:
-
- printf \"\\e]7;file://%s%s\\e\\\\\" \"$HOSTNAME\" \"$PWD\"
-
-This functionality serves as an alternative to `dirtrack-mode'
-and `shell-dirtrack-mode'."
- (let ((url (url-generic-parse-url text)))
- (when (and (string= (url-type url) "file")
- (or (null (url-host url))
- (string= (url-host url) (system-name))))
- (ignore-errors
- (cd-absolute (url-unhex-string (url-filename url)))))))
-
-;; Hyperlink handling (OSC 8)
-
-(defvar comint-osc-hyperlink-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c\r" 'browse-url-button-open)
- (define-key map [mouse-2] 'browse-url-button-open)
- (define-key map [follow-link] 'mouse-face)
- map)
- "Keymap used by OSC 8 hyperlink buttons.")
-
-(define-button-type 'comint-osc-hyperlink
- 'keymap comint-osc-hyperlink-map
- 'help-echo (lambda (_ buffer pos)
- (when-let ((url (get-text-property pos 'browse-url-data buffer)))
- (format "mouse-2, C-c RET: Open %s" url))))
-
-(defvar-local comint-osc-hyperlink--state nil)
-
-(defun comint-osc-hyperlink-handler (_ text)
- "Create a hyperlink from an OSC 8 escape sequence.
-This function is intended to be included as an entry of
-`comint-osc-handlers'."
- (when comint-osc-hyperlink--state
- (let ((start (car comint-osc-hyperlink--state))
- (url (cdr comint-osc-hyperlink--state)))
- (make-text-button start (point)
- 'type 'comint-osc-hyperlink
- 'browse-url-data url)))
- (setq comint-osc-hyperlink--state
- (and (string-match ";\\(.+\\)" text)
- (cons (point-marker) (match-string-no-properties 1 text)))))
+ (let ((start (1- comint-last-output-start))
+ ;; Start one char before last output to catch a possibly stray ESC
+ (bound (process-mark (get-buffer-process (current-buffer)))))
+ (ansi-osc-apply-on-region start bound)))
;;; Input fontification and indentation through an indirect buffer
@@ -4036,7 +3972,7 @@ an indirect buffer, whose major mode and syntax highlighting are
set up according to `comint-indirect-setup-function'. After this
setup is done, run this hook with the indirect buffer as the
current buffer. This can be used to further customize
-fontification and other behaviour of the indirect buffer."
+fontification and other behavior of the indirect buffer."
:group 'comint
:type 'hook
:version "29.1")
@@ -4044,9 +3980,9 @@ fontification and other behaviour of the indirect buffer."
(defvar-local comint--indirect-buffer nil
"Indirect buffer used for input fontification.")
-(defvar-local comint--fl-saved-jit-lock-contextually nil)
+(defvar-local comint--fontify-input-saved-jit-lock-contextually nil)
-(define-minor-mode comint-fl-mode
+(define-minor-mode comint-fontify-input-mode
"Enable input fontification in the current comint buffer.
This minor mode is useful if the current major mode derives from
`comint-mode' and if `comint-indirect-setup-function' is set.
@@ -4061,71 +3997,71 @@ This function signals an error if `comint-use-prompt-regexp' is
non-nil. Input fontification isn't compatible with this
setting."
:lighter nil
- (if comint-fl-mode
+ (if comint-fontify-input-mode
(let ((success nil))
(unwind-protect
(progn
- (comint--fl-on)
+ (comint--fontify-input-on)
(setq success t))
(unless success
- (setq comint-fl-mode nil)
- (comint--fl-off))))
- (comint--fl-off)))
+ (setq comint-fontify-input-mode nil)
+ (comint--fontify-input-off))))
+ (comint--fontify-input-off)))
-(defun comint--fl-on ()
+(defun comint--fontify-input-on ()
"Enable input fontification in the current comint buffer."
- (comint--fl-off)
+ (comint--fontify-input-off)
(when comint-use-prompt-regexp
(error
"Input fontification is incompatible with `comint-use-prompt-regexp'"))
(add-function :around (local 'font-lock-fontify-region-function)
- #'comint--fl-fontify-region)
+ #'comint--fontify-input-fontify-region)
;; `before-change-functions' are only run in the current buffer and
;; not in its indirect buffers, which means that we must manually
;; flush ppss cache
(add-hook 'before-change-functions
- #'comint--fl-ppss-flush-indirect 99 t)
+ #'comint--fontify-input-ppss-flush-indirect 99 t)
;; Set up contextual fontification
(unless (booleanp jit-lock-contextually)
- (setq comint--fl-saved-jit-lock-contextually
+ (setq comint--fontify-input-saved-jit-lock-contextually
jit-lock-contextually)
(setq-local jit-lock-contextually t)
(when jit-lock-mode
(jit-lock-mode t))))
-(defun comint--fl-off ()
+(defun comint--fontify-input-off ()
"Disable input fontification in the current comint buffer."
(remove-function (local 'font-lock-fontify-region-function)
- #'comint--fl-fontify-region)
+ #'comint--fontify-input-fontify-region)
(remove-hook 'before-change-functions
- #'comint--fl-ppss-flush-indirect t)
+ #'comint--fontify-input-ppss-flush-indirect t)
;; Reset contextual fontification
- (when comint--fl-saved-jit-lock-contextually
+ (when comint--fontify-input-saved-jit-lock-contextually
(setq-local jit-lock-contextually
- comint--fl-saved-jit-lock-contextually)
- (setq comint--fl-saved-jit-lock-contextually nil)
+ comint--fontify-input-saved-jit-lock-contextually)
+ (setq comint--fontify-input-saved-jit-lock-contextually nil)
(when jit-lock-mode
(jit-lock-mode t)))
(font-lock-flush))
-(defun comint--fl-ppss-flush-indirect (beg &rest rest)
+(defun comint--fontify-input-ppss-flush-indirect (beg &rest rest)
(when-let ((buf (comint-indirect-buffer t)))
(with-current-buffer buf
(when (memq #'syntax-ppss-flush-cache before-change-functions)
(apply #'syntax-ppss-flush-cache beg rest)))))
-(defun comint--fl-fontify-region (fun beg end verbose)
+(defun comint--fontify-input-fontify-region (fun beg end verbose)
"Fontify process output and user input in the current comint buffer.
First, fontify the region between BEG and END using FUN. Then
fontify only the input text in the region with the help of an
indirect buffer. VERBOSE is passed to the fontify-region
functions. Skip fontification of input regions with non-nil
-`comint--fl-inhibit-fontification' text property."
+`comint--fontify-input-inhibit-fontification' text property."
(pcase (funcall fun beg end verbose)
(`(jit-lock-bounds ,beg1 . ,end1)
(setq beg beg1 end end1)))
@@ -4137,7 +4073,7 @@ functions. Skip fontification of input regions with non-nil
(comint--intersect-regions
nil (lambda (beg end)
(unless (get-text-property
- beg 'comint--fl-inhibit-fontification)
+ beg 'comint--fontify-input-inhibit-fontification)
(font-lock-fontify-region beg end verbose)))
beg end)))
(`((jit-lock-bounds ,beg1 . ,_) . (jit-lock-bounds ,_ . ,end1))
diff --git a/lisp/cus-dep.el b/lisp/cus-dep.el
index bb07a0694a1..3f18202affe 100644
--- a/lisp/cus-dep.el
+++ b/lisp/cus-dep.el
@@ -175,7 +175,7 @@ Usage: emacs -batch -l ./cus-dep.el -f custom-make-dependencies DIRS"
(prin1 (sort found #'string<))))
alist))))))
(dolist (e (sort alist (lambda (e1 e2) (string< (car e1) (car e2)))))
- (insert "(put '" (car e) " 'custom-loads '" (cdr e) ")\n")))
+ (insert "(custom--add-custom-loads '" (car e) " '" (cdr e) ")\n")))
(insert "\
;; The remainder of this file is for handling :version.
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 0e1cb4589da..d7fb56c9854 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -251,7 +251,6 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
;; emacs.c
(report-emacs-bug-address emacsbug string)
;; eval.c
- (max-specpdl-size limits integer)
(max-lisp-eval-depth limits integer)
(max-mini-window-height limits
(choice (const :tag "quarter screen" nil)
diff --git a/lisp/custom.el b/lisp/custom.el
index 352b5b0e160..0d3e2e5d0c2 100644
--- a/lisp/custom.el
+++ b/lisp/custom.el
@@ -1152,9 +1152,11 @@ list, in which A occurs before B if B was defined with a
;; (provide-theme 'THEME)
-(defmacro deftheme (theme &optional doc)
+(defmacro deftheme (theme &optional doc &rest properties)
"Declare THEME to be a Custom theme.
The optional argument DOC is a doc string describing the theme.
+PROPERTIES are interpreted as a property list that will be stored
+in the `theme-properties' property for THEME.
Any theme `foo' should be defined in a file called `foo-theme.el';
see `custom-make-theme-feature' for more information."
@@ -1164,18 +1166,25 @@ see `custom-make-theme-feature' for more information."
;; It is better not to use backquote in this file,
;; because that makes a bootstrapping problem
;; if you need to recompile all the Lisp files using interpreted code.
- (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc)))
+ (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc
+ (cons 'list properties))))
-(defun custom-declare-theme (theme feature &optional doc)
+(defun custom-declare-theme (theme feature &optional doc properties)
"Like `deftheme', but THEME is evaluated as a normal argument.
-FEATURE is the feature this theme provides. Normally, this is a symbol
-created from THEME by `custom-make-theme-feature'."
+FEATURE is the feature this theme provides. Normally, this is a
+symbol created from THEME by `custom-make-theme-feature'. The
+optional argument DOC may contain the documentation for THEME.
+The optional argument PROPERTIES may contain a property list of
+attributes associated with THEME."
(unless (custom-theme-name-valid-p theme)
(error "Custom theme cannot be named %S" theme))
(unless (memq theme custom-known-themes)
(push theme custom-known-themes))
(put theme 'theme-feature feature)
- (when doc (put theme 'theme-documentation doc)))
+ (when doc
+ (put theme 'theme-documentation doc))
+ (when properties
+ (put theme 'theme-properties properties)))
(defun custom-make-theme-feature (theme)
"Given a symbol THEME, create a new symbol by appending \"-theme\".
@@ -1372,6 +1381,58 @@ Return t if THEME was successfully loaded, nil otherwise."
(enable-theme theme))
t)
+(defun theme-list-variants (theme &rest list)
+ "Return a list of theme variants for THEME.
+By default this will use all known custom themes (see
+`custom-available-themes') to check for variants. This can be
+restricted if the optional argument LIST containing a list of
+theme symbols to consider."
+ (let* ((properties (get theme 'theme-properties))
+ (family (plist-get properties :family)))
+ (seq-filter
+ (lambda (variant)
+ (and (eq (plist-get (get variant 'theme-properties) :family)
+ family)
+ (not (eq variant theme))))
+ (or list (custom-available-themes)))))
+
+(defun theme-choose-variant (&optional no-confirm no-enable)
+ "Switch from the current theme to one of its variants.
+The current theme will be disabled before variant is enabled. If
+the current theme has only one variant, switch to that variant
+without prompting, otherwise prompt for the variant to select.
+See `load-theme' for the meaning of NO-CONFIRM and NO-ENABLE."
+ (interactive)
+ (let ((active-color-schemes
+ (seq-filter
+ (lambda (theme)
+ ;; FIXME: As most themes currently do not have a `:kind'
+ ;; tag, it is assumed that a theme is a color scheme by
+ ;; default. This should be reconsidered in the future.
+ (memq (plist-get (get theme 'theme-properties) :kind)
+ '(color-scheme nil)))
+ custom-enabled-themes)))
+ (cond
+ ((length= active-color-schemes 0)
+ (user-error "No theme is active, cannot toggle"))
+ ((length> active-color-schemes 1)
+ (user-error "More than one theme active, cannot unambiguously toggle")))
+ (let* ((theme (car active-color-schemes))
+ (family (plist-get (get theme 'theme-properties) :family)))
+ (unless family
+ (error "Theme `%s' does not have any known variants" theme))
+ (let* ((variants (theme-list-variants theme))
+ (choice (cond
+ ((null variants)
+ (error "`%s' has no variants" theme))
+ ((length= variants 1)
+ (car variants))
+ ((intern (completing-read "Load custom theme: " variants))))))
+ (disable-theme theme)
+ (load-theme choice no-confirm no-enable)))))
+
+(defalias 'toggle-theme #'theme-choose-variant)
+
(defun custom-theme-load-confirm (hash)
"Query the user about loading a Custom theme that may not be safe.
The theme should be in the current buffer. If the user agrees,
@@ -1707,6 +1768,13 @@ If a choice with the same tag already exists, no action is taken."
(put variable 'custom-type
(append choices (list choice))))))
+(defun custom--add-custom-loads (symbol loads)
+ ;; Don't overwrite existing `custom-loads'.
+ (dolist (load (get symbol 'custom-loads))
+ (unless (memq load loads)
+ (push load loads)))
+ (put symbol 'custom-loads loads))
+
(provide 'custom)
;;; custom.el ends here
diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el
index 215425f1367..e909da3c207 100644
--- a/lisp/dabbrev.el
+++ b/lisp/dabbrev.el
@@ -985,9 +985,6 @@ Leaves point at the location of the start of the expansion."
"\\(" dabbrev--abbrev-char-regexp "\\)"))
(pattern2 (concat (regexp-quote abbrev)
"\\(\\(" dabbrev--abbrev-char-regexp "\\)+\\)"))
- ;; This makes it possible to find matches in minibuffer prompts
- ;; even when they are "inviolable".
- (inhibit-point-motion-hooks t)
found-string result)
;; Limited search.
(save-restriction
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index f870494e93e..9add96c2608 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -2880,6 +2880,10 @@ of `dired-dwim-target', which see.
Also see `dired-do-revert-buffer'."
(interactive "P")
+ (when (seq-find (lambda (file)
+ (member (file-name-nondirectory file) '("." "..")))
+ (dired-get-marked-files nil arg))
+ (user-error "Can't rename \".\" or \"..\" files"))
(dired-do-create-files 'move #'dired-rename-file
"Move" arg dired-keep-marker-rename "Rename"))
diff --git a/lisp/dired.el b/lisp/dired.el
index b9e89292e25..85a71315702 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -2956,7 +2956,7 @@ unchanged."
(or dir (setq dir default-directory))
;; This case comes into play if default-directory is set to
;; use ~.
- (if (and (> (length dir) 0) (= (aref dir 0) ?~))
+ (if (string-match-p "\\(\\`\\|:\\)~" dir)
(setq dir (expand-file-name dir)))
(if (string-match (concat "^" (regexp-quote dir)) file)
(substring file (match-end 0))
@@ -3664,16 +3664,16 @@ non-empty directories is allowed."
case-fold-search markers)
(if (save-excursion (goto-char (point-min))
(re-search-forward regexp nil t))
- (dired-internal-do-deletions
- (nreverse
- ;; this can't move point since ARG is nil
- (dired-map-over-marks (cons (dired-get-filename)
- (let ((m (point-marker)))
- (push m markers)
- m))
- nil))
- nil t)
- (dolist (m markers) (set-marker m nil))
+ (progn
+ (dired-internal-do-deletions
+ (nreverse
+ (dired-map-over-marks (cons (dired-get-filename)
+ (let ((m (point-marker)))
+ (push m markers)
+ m))
+ nil))
+ nil t)
+ (dolist (m markers) (set-marker m nil)))
(or nomessage
(message "(No deletions requested)")))))
diff --git a/lisp/dnd.el b/lisp/dnd.el
index 70852885a86..b2e93a63def 100644
--- a/lisp/dnd.el
+++ b/lisp/dnd.el
@@ -370,8 +370,8 @@ currently being held down. It should only be called upon a
;; the standard (i.e. Qt programs).
"text/plain" "text/plain;charset=utf-8")
(cl-ecase action
- ('copy 'XdndActionCopy)
- ('move 'XdndActionMove))
+ (copy 'XdndActionCopy)
+ (move 'XdndActionMove))
frame nil allow-same-frame)))
(cond
((eq return-value 'XdndActionCopy) 'copy)
@@ -457,9 +457,9 @@ currently being held down. It should only be called upon a
;; programs.
"_DT_NETFILE")
(cl-ecase action
- ('copy 'XdndActionCopy)
- ('move 'XdndActionMove)
- ('link 'XdndActionLink))
+ (copy 'XdndActionCopy)
+ (move 'XdndActionMove)
+ (link 'XdndActionLink))
frame nil allow-same-frame)))
(cond
((eq return-value 'XdndActionCopy) 'copy)
@@ -527,9 +527,9 @@ FILES will be dragged."
;; and Haiku.
"FILE_NAME" "HOST_NAME")
(cl-ecase action
- ('copy 'XdndActionCopy)
- ('move 'XdndActionMove)
- ('link 'XdndActionLink))
+ (copy 'XdndActionCopy)
+ (move 'XdndActionMove)
+ (link 'XdndActionLink))
frame nil allow-same-frame)))
(cond
((eq return-value 'XdndActionCopy) 'copy)
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index aa0f9fd3838..b1ea90c212b 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -209,6 +209,45 @@ are available (see Info node `(emacs)Document View')."
function)
:version "24.4")
+(defcustom doc-view-mupdf-use-svg (image-type-available-p 'svg)
+ "Whether to use svg images for PDF files."
+ :type 'boolean
+ :version "29.1")
+
+(defcustom doc-view-imenu-enabled (and (executable-find "mutool") t)
+ "Whether to generate an imenu outline when \"mutool\" is available."
+ :type 'boolean
+ :version "29.1")
+
+(defcustom doc-view-imenu-title-format "%t (%p)"
+ "Format spec for imenu's display of section titles from docview documents.
+
+The special markers '%t' and '%p' are replaced by the section
+title and page number in this format string, which uses
+`format-spec'.
+
+For instance, setting this variable to \"%t\" will produce items
+showing only titles and no page number."
+ :type 'string
+ :version "29.1")
+
+(defcustom doc-view-imenu-flatten nil
+ "Whether to flatten the list of sections in an imenu or show it nested."
+ :type 'boolean
+ :version "29.1")
+
+(defcustom doc-view-svg-background "white"
+ "Background color for svg images.
+See `doc-view-mupdf-use-svg'."
+ :type 'color
+ :version "29.1")
+
+(defcustom doc-view-svg-foreground "black"
+ "Foreground color for svg images.
+See `doc-view-mupdf-use-svg'."
+ :type 'color
+ :version "29.1")
+
(defcustom doc-view-ghostscript-options
'("-dSAFER" ;; Avoid security problems when rendering files from untrusted
;; sources.
@@ -1562,6 +1601,9 @@ ARGS is a list of image descriptors."
(setq args `(,@args :width ,doc-view-image-width)))
(unless (member :transform-smoothing args)
(setq args `(,@args :transform-smoothing t)))
+ (when (eq doc-view--image-type 'svg)
+ (setq args `(,@args :background ,doc-view-svg-background
+ :foreground ,doc-view-svg-foreground)))
(apply #'create-image file doc-view--image-type nil args))))
(slice (doc-view-current-slice))
(img-width (and image (car (image-size image))))
@@ -1854,6 +1896,81 @@ If BACKWARD is non-nil, jump to the previous match."
(y-or-n-p "No more matches before current page. Wrap to last match? "))
(doc-view-goto-page (caar (last doc-view--current-search-matches)))))))
+;;;; Imenu support
+(defconst doc-view--outline-rx
+ "[^\t]+\\(\t+\\)\"\\(.+\\)\"\t#\\(?:page=\\)?\\([0-9]+\\)")
+
+(defvar-local doc-view--outline nil
+ "Cached PDF outline, so that it is only computed once per document.")
+
+(defun doc-view--pdf-outline (&optional file-name)
+ "Return a list describing the outline of FILE-NAME.
+Return a list describing the current file if FILE-NAME is nil.
+
+Each element in the returned list contains information about a section's
+title, nesting level and page number. The list is flat: its tree
+structure is extracted by `doc-view--imenu-subtree'."
+ (let ((fn (or file-name (buffer-file-name))))
+ (when fn
+ (let ((outline nil)
+ (fn (shell-quote-argument (expand-file-name fn))))
+ (with-temp-buffer
+ (insert (shell-command-to-string (format "mutool show %s outline" fn)))
+ (goto-char (point-min))
+ (while (re-search-forward doc-view--outline-rx nil t)
+ (push `((level . ,(length (match-string 1)))
+ (title . ,(replace-regexp-in-string "\\\\[rt]" " "
+ (match-string 2)))
+ (page . ,(string-to-number (match-string 3))))
+ outline)))
+ (nreverse outline)))))
+
+(defun doc-view--imenu-subtree (outline act)
+ "Construct a tree of imenu items for the given outline list and action.
+
+This auxliary function constructs recursively all the items for
+the first node in the outline and all its siblings at the same
+level. Returns that imenu alist together with any other pending outline
+entries at an upper level."
+ (let ((level (alist-get 'level (car outline)))
+ (nested (not doc-view-imenu-flatten))
+ (index nil))
+ (while (and (car outline)
+ (or (not nested)
+ (<= level (alist-get 'level (car outline)))))
+ (let-alist (car outline)
+ (let ((title (format-spec doc-view-imenu-title-format
+ `((?t . ,.title) (?p . ,.page)))))
+ (if (and nested (> .level level))
+ (let ((sub (doc-view--imenu-subtree outline act))
+ (fst (car index)))
+ (setq index (cdr index))
+ (push (cons (car fst) (cons fst (car sub))) index)
+ (setq outline (cdr sub)))
+ (push `(,title 0 ,act ,.page) index)
+ (setq outline (cdr outline))))))
+ (cons (nreverse index) outline)))
+
+(defun doc-view-imenu-index (&optional file-name goto-page-fn)
+ "Create an imenu index using \"mutool\" to extract its outline.
+
+For extensibility, callers can specify a FILE-NAME to indicate
+the buffer other than the current buffer, and a jumping function
+GOTO-PAGE-FN other than `doc-view-goto-page'."
+ (let* ((goto (or goto-page-fn 'doc-view-goto-page))
+ (act (lambda (_name _pos page) (funcall goto page)))
+ (outline (or doc-view--outline (doc-view--pdf-outline file-name))))
+ (car (doc-view--imenu-subtree outline act))))
+
+(defun doc-view-imenu-setup ()
+ "Set up local state in the current buffer for imenu, if needed."
+ (when (and doc-view-imenu-enabled (executable-find "mutool"))
+ (setq-local imenu-create-index-function #'doc-view-imenu-index
+ imenu-submenus-on-top nil
+ imenu-sort-function nil
+ doc-view--outline (doc-view--pdf-outline))
+ (when doc-view--outline (imenu-add-to-menubar "Outline"))))
+
;;;; User interface commands and the mode
(put 'doc-view-mode 'mode-class 'special)
@@ -1983,7 +2100,11 @@ If BACKWARD is non-nil, jump to the previous match."
(pcase-let ((`(,conv-function ,type ,extension)
(pcase doc-view-doc-type
('djvu (list #'doc-view-djvu->tiff-converter-ddjvu 'tiff "tif"))
- (_ (list doc-view-pdf->png-converter-function 'png "png")))))
+ (_ (if (and (eq doc-view-pdf->png-converter-function
+ #'doc-view-pdf->png-converter-mupdf)
+ doc-view-mupdf-use-svg)
+ (list doc-view-pdf->png-converter-function 'svg "svg")
+ (list doc-view-pdf->png-converter-function 'png "png"))))))
(setq-local doc-view-single-page-converter-function conv-function)
(setq-local doc-view--image-type type)
(setq-local doc-view--image-file-pattern (concat "page-%s." extension))))
@@ -2023,7 +2144,7 @@ If BACKWARD is non-nil, jump to the previous match."
"Major mode in DocView buffers.
DocView Mode is an Emacs document viewer. It displays PDF, PS
-and DVI files (as PNG images) in Emacs buffers.
+and DVI files (as PNG or SVG images) in Emacs buffers.
You can use \\<doc-view-mode-map>\\[doc-view-toggle-display] to
toggle between displaying the document or editing it as text.
@@ -2118,6 +2239,7 @@ toggle between displaying the document or editing it as text.
(setq mode-name "DocView"
buffer-read-only t
major-mode 'doc-view-mode)
+ (doc-view-imenu-setup)
(doc-view-initiate-display)
;; Switch off view-mode explicitly, because doc-view-mode is the
;; canonical view mode for PDF/PS/DVI files. This could be
diff --git a/lisp/ecomplete.el b/lisp/ecomplete.el
index 76438fd25a7..54d60c84d4f 100644
--- a/lisp/ecomplete.el
+++ b/lisp/ecomplete.el
@@ -70,9 +70,9 @@
:type '(symbol :tag "Coding system"))
(defcustom ecomplete-sort-predicate #'ecomplete-decay
- "Predicate to use when sorting matched.
-The predicate is called with two parameters that represent the
-completion. Each parameter is a list where the first element is
+ "Predicate to use when sorting matched ecomplete candidates.
+The predicate is called with two arguments that represent the
+completion. Each argument is a list where the first element is
the times the completion has been used, the second is the
timestamp of the most recent usage, and the third item is the
string that was matched."
@@ -86,6 +86,11 @@ string that was matched."
:type 'boolean
:version "29.1")
+(defcustom ecomplete-filter-regexp nil
+ "Regular expression of addresses that should not be stored by ecomplete."
+ :type 'regexp
+ :version "29.1")
+
;;; Internal variables.
(defvar ecomplete-database nil)
@@ -99,21 +104,39 @@ string that was matched."
(insert-file-contents ecomplete-database-file)
(setq ecomplete-database (read (current-buffer)))))))
-(defun ecomplete-add-item (type key text)
- "Add item TEXT of TYPE to the database, using KEY as the identifier."
+(defun ecomplete-add-item (type key text &optional force)
+ "Add item TEXT of TYPE to the database, using KEY as the identifier.
+By default, the longest version of TEXT will be preserved, but if
+FORCE is non-nil, use TEXT exactly as is."
(unless ecomplete-database (ecomplete-setup))
- (let ((elems (assq type ecomplete-database))
- (now (time-convert nil 'integer))
- entry)
+ (unless (and ecomplete-filter-regexp
+ (string-match-p ecomplete-filter-regexp key))
+ (let ((elems (assq type ecomplete-database))
+ (now (time-convert nil 'integer))
+ entry)
+ (unless elems
+ (push (setq elems (list type)) ecomplete-database))
+ (if (setq entry (assoc key (cdr elems)))
+ (pcase-let ((`(,_key ,count ,_time ,oldtext) entry))
+ (setcdr entry (list (1+ count) now
+ ;; Preserve the "more complete" text.
+ (if (or force
+ (>= (length text) (length oldtext)))
+ text
+ oldtext))))
+ (nconc elems (list (list key 1 now text)))))))
+
+(defun ecomplete--remove-item (type key)
+ "Remove the element of TYPE and KEY from the ecomplete database."
+ (unless ecomplete-database
+ (ecomplete-setup))
+ (let ((elems (assq type ecomplete-database)))
(unless elems
- (push (setq elems (list type)) ecomplete-database))
- (if (setq entry (assoc key (cdr elems)))
- (pcase-let ((`(,_key ,count ,_time ,oldtext) entry))
- (setcdr entry (list (1+ count) now
- ;; Preserve the "more complete" text.
- (if (>= (length text) (length oldtext))
- text oldtext))))
- (nconc elems (list (list key 1 now text))))))
+ (user-error "No elements of type %s" type))
+ (let ((entry (assoc key elems)))
+ (unless entry
+ (user-error "No entry with key %s" key))
+ (setcdr elems (delq entry (cdr elems))))))
(defun ecomplete-get-item (type key)
"Return the text for the item identified by KEY of the required TYPE."
@@ -263,6 +286,54 @@ non-nil and there is only a single completion option available."
ecomplete-sort-predicate))))
(complete-with-action action candidates string pred))))))
+(defun ecomplete--prompt-type ()
+ (unless ecomplete-database
+ (ecomplete-setup))
+ (if (length= ecomplete-database 1)
+ (caar ecomplete-database)
+ (completing-read "Item type to edit: "
+ (mapcar #'car ecomplete-database)
+ nil t)))
+
+(defun ecomplete-edit ()
+ "Prompt for an ecomplete item and allow editing it."
+ (interactive)
+ (let* ((type (ecomplete--prompt-type))
+ (data (cdr (assq type ecomplete-database)))
+ (key (completing-read "Key to edit: " data nil t))
+ (new (read-string "New value (empty to remove): "
+ (nth 3 (assoc key data)))))
+ (if (zerop (length new))
+ (progn
+ (ecomplete--remove-item type key)
+ (message "Removed %s" key))
+ (ecomplete-add-item type key new t)
+ (message "Updated %s to %s" key new))
+ (ecomplete-save)))
+
+(defun ecomplete-remove ()
+ "Remove from the ecomplete database the entries matching a regexp.
+Prompt for the regexp to match the database entries to be removed."
+ (interactive)
+ (let* ((type (ecomplete--prompt-type))
+ (data (cdr (assq type ecomplete-database)))
+ (match (read-regexp (format "Remove %s keys matching (regexp): "
+ type)))
+ (elems (seq-filter (lambda (elem)
+ (string-match-p match (car elem)))
+ data)))
+ (if (length= elems 0)
+ (message "No matching entries for %s" match)
+ (when (yes-or-no-p (format "Delete %s matching ecomplete %s? "
+ (length elems)
+ (if (length= elems 1)
+ "entry"
+ "entries")))
+ (dolist (elem elems)
+ (ecomplete--remove-item type (car elem)))
+ (ecomplete-save)
+ (message "Deleted entries")))))
+
(provide 'ecomplete)
;;; ecomplete.el ends here
diff --git a/lisp/emacs-lisp/benchmark.el b/lisp/emacs-lisp/benchmark.el
index 882b1d68c48..4bf61abe54c 100644
--- a/lisp/emacs-lisp/benchmark.el
+++ b/lisp/emacs-lisp/benchmark.el
@@ -31,6 +31,7 @@
;;; Code:
+(require 'cl-lib)
(eval-when-compile (require 'subr-x)) ;For `named-let'.
(defmacro benchmark-elapse (&rest forms)
@@ -70,7 +71,7 @@ number of repetitions actually used."
(defun benchmark--adaptive (func time)
"Measure the run time of FUNC, calling it enough times to last TIME seconds.
-Result is (REPETITIONS . DATA) where DATA is as returned by `branchmark-call'."
+Result is (REPETITIONS . DATA) where DATA is as returned by `benchmark-call'."
(named-let loop ((repetitions 1)
(data (let ((x (list 0))) (setcdr x x) x)))
;; (message "Running %d iteration" repetitions)
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 27b0d33d3ef..5ef2d7fe827 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -737,7 +737,7 @@ for speeding up processing.")
reverse nreverse sort))
(setq form (nth 1 form))
t)
- ((memq head '(mapc setq setcar setcdr puthash))
+ ((memq head '(mapc setq setcar setcdr puthash set))
(setq form (nth 2 form))
t)
((memq head '(aset put function-put))
@@ -793,6 +793,7 @@ for speeding up processing.")
sxhash sxhash-equal sxhash-eq sxhash-eql
sxhash-equal-including-properties
make-marker copy-marker point-marker mark-marker
+ set-marker
kbd key-description
always))
t)
@@ -811,7 +812,7 @@ for speeding up processing.")
(defun byte-compile-nilconstp (form)
"Return non-nil if FORM always evaluates to a nil value."
(setq form (byte-opt--bool-value-form form))
- (or (not form) ; assume (quote nil) always being normalised to nil
+ (or (not form) ; assume (quote nil) always being normalized to nil
(and (consp form)
(let ((head (car form)))
;; FIXME: There are many other expressions that are statically nil.
@@ -1183,7 +1184,7 @@ See Info node `(elisp) Integer Basics'."
(if (equal new-args (cdr form))
;; Input is unchanged: keep original form, and don't represent
;; a nil result explicitly because that would lead to infinite
- ;; growth when the optimiser is iterated.
+ ;; growth when the optimizer is iterated.
(setq nil-result nil)
(setq form (cons (car form) new-args)))
@@ -1531,15 +1532,16 @@ See Info node `(elisp) Integer Basics'."
(put 'set 'byte-optimizer #'byte-optimize-set)
(defun byte-optimize-set (form)
- (let ((var (car-safe (cdr-safe form))))
- (cond
- ((and (eq (car-safe var) 'quote) (consp (cdr var)))
- `(setq ,(cadr var) ,@(cddr form)))
- ((and (eq (car-safe var) 'make-local-variable)
- (eq (car-safe (setq var (car-safe (cdr var)))) 'quote)
- (consp (cdr var)))
- `(progn ,(cadr form) (setq ,(cadr var) ,@(cddr form))))
- (t form))))
+ (pcase (cdr form)
+ ;; Make sure we only turn `set' into `setq' for dynamic variables.
+ (`((quote ,(and var (guard (and (symbolp var)
+ (not (macroexp--const-symbol-p var))
+ (not (assq var byte-optimize--lexvars))))))
+ ,newval)
+ `(setq ,var ,newval))
+ (`(,(and ml `(make-local-variable ,(and v `(quote ,_)))) ,newval)
+ `(progn ,ml (,(car form) ,v ,newval)))
+ (_ form)))
;; enumerating those functions which need not be called if the returned
;; value is not used. That is, something like
@@ -1999,20 +2001,20 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance."
(setq keep-going t)
(setq tmp (aref byte-stack+-info (symbol-value (car lap0))))
(setq rest (cdr rest))
- (cond ((= tmp 1)
+ (cond ((eql tmp 1)
(byte-compile-log-lap
" %s discard\t-->\t<deleted>" lap0)
(setq lap (delq lap0 (delq lap1 lap))))
- ((= tmp 0)
+ ((eql tmp 0)
(byte-compile-log-lap
" %s discard\t-->\t<deleted> discard" lap0)
(setq lap (delq lap0 lap)))
- ((= tmp -1)
+ ((eql tmp -1)
(byte-compile-log-lap
" %s discard\t-->\tdiscard discard" lap0)
(setcar lap0 'byte-discard)
(setcdr lap0 0))
- ((error "Optimizer error: too much on the stack"))))
+ (t (error "Optimizer error: too much on the stack"))))
;;
;; goto*-X X: --> X:
;;
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 48929e62bdf..74ba8984f29 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1469,9 +1469,11 @@ when printing the error message."
(defun byte-compile-arglist-signature-string (signature)
(cond ((null (cdr signature))
- (format "%d+" (car signature)))
+ (format "%d or more" (car signature)))
((= (car signature) (cdr signature))
(format "%d" (car signature)))
+ ((= (1+ (car signature)) (cdr signature))
+ (format "%d or %d" (car signature) (cdr signature)))
(t (format "%d-%d" (car signature) (cdr signature)))))
(defun byte-compile-function-warn (f nargs def)
@@ -1705,12 +1707,12 @@ URLs."
(+ " " (or
;; Arguments.
(+ (or (syntax symbol)
- (any word "-/:[]&=().?^\\#'")))
+ (any word "-/:[]&=()<>.,?^\\#*'\"")))
;; Argument that is a list.
(seq "(" (* (not ")")) ")")))
")")))
""
- ;; Heuristic: We can't reliably do `subsititute-command-keys'
+ ;; Heuristic: We can't reliably do `substitute-command-keys'
;; substitutions, since the value of a keymap in general can't be
;; known at compile time. So instead, we assume that these
;; substitutions are of some length N.
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el
index 7f95fa94fa1..23d0f121948 100644
--- a/lisp/emacs-lisp/cconv.el
+++ b/lisp/emacs-lisp/cconv.el
@@ -137,6 +137,11 @@ is less than this number.")
;; Alist associating to each function body the list of its free variables.
)
+(defvar cconv--interactive-form-funs
+ ;; Table used to hold the functions we create internally for
+ ;; interactive forms.
+ (make-hash-table :test #'eq :weakness 'key))
+
;;;###autoload
(defun cconv-closure-convert (form)
"Main entry point for closure conversion.
@@ -503,9 +508,23 @@ places where they originally did not directly appear."
cond-forms)))
(`(function (lambda ,args . ,body) . ,_)
- (let ((docstring (if (eq :documentation (car-safe (car body)))
- (cconv-convert (cadr (pop body)) env extend))))
- (cconv--convert-function args body env form docstring)))
+ (let* ((docstring (if (eq :documentation (car-safe (car body)))
+ (cconv-convert (cadr (pop body)) env extend)))
+ (bf (if (stringp (car body)) (cdr body) body))
+ (if (when (eq 'interactive (car-safe (car bf)))
+ (gethash form cconv--interactive-form-funs)))
+ (cif (when if (cconv-convert if env extend)))
+ (_ (pcase cif
+ (`#'(lambda () ,form) (setf (cadr (car bf)) form) (setq cif nil))
+ ('nil nil)
+ ;; The interactive form needs special treatment, so the form
+ ;; inside the `interactive' won't be used any further.
+ (_ (setf (cadr (car bf)) nil))))
+ (cf (cconv--convert-function args body env form docstring)))
+ (if (not cif)
+ ;; Normal case, the interactive form needs no special treatment.
+ cf
+ `(cconv--interactive-helper ,cf ,cif))))
(`(internal-make-closure . ,_)
(byte-compile-report-error
@@ -589,12 +608,12 @@ places where they originally did not directly appear."
(cconv-convert arg env extend))
(cons fun args)))))))
- (`(interactive . ,forms)
- `(,(car form) . ,(mapcar (lambda (form)
- (cconv-convert form nil nil))
- forms)))
+ ;; The form (if any) is converted beforehand as part of the `lambda' case.
+ (`(interactive . ,_) form)
- (`(declare . ,_) form) ;The args don't contain code.
+ ;; `declare' should now be macro-expanded away (and if they're not, we're
+ ;; in trouble because they *can* contain code nowadays).
+ ;; (`(declare . ,_) form) ;The args don't contain code.
(`(oclosure--fix-type (ignore . ,vars) ,exp)
(dolist (var vars)
@@ -739,6 +758,13 @@ This function does not return anything but instead fills the
(`(function (lambda ,vrs . ,body-forms))
(when (eq :documentation (car-safe (car body-forms)))
(cconv-analyze-form (cadr (pop body-forms)) env))
+ (let ((bf (if (stringp (car body-forms)) (cdr body-forms) body-forms)))
+ (when (eq 'interactive (car-safe (car bf)))
+ (let ((if (cadr (car bf))))
+ (unless (macroexp-const-p if) ;Optimize this common case.
+ (let ((f `#'(lambda () ,if)))
+ (setf (gethash form cconv--interactive-form-funs) f)
+ (cconv-analyze-form f env))))))
(cconv--analyze-function vrs body-forms env form))
(`(setq ,var ,expr)
@@ -803,13 +829,8 @@ This function does not return anything but instead fills the
(cconv-analyze-form fun env)))
(dolist (form args) (cconv-analyze-form form env)))
- (`(interactive . ,forms)
- ;; These appear within the function body but they don't have access
- ;; to the function's arguments.
- ;; We could extend this to allow interactive specs to refer to
- ;; variables in the function's enclosing environment, but it doesn't
- ;; seem worth the trouble.
- (dolist (form forms) (cconv-analyze-form form nil)))
+ ;; The form (if any) is converted beforehand as part of the `lambda' case.
+ (`(interactive . ,_) nil)
;; `declare' should now be macro-expanded away (and if they're not, we're
;; in trouble because they *can* contain code nowadays).
diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el
index 20d64b59158..3f9bc28e0b0 100644
--- a/lisp/emacs-lisp/checkdoc.el
+++ b/lisp/emacs-lisp/checkdoc.el
@@ -250,7 +250,7 @@ with these words enabled."
(defvar checkdoc-ispell-lisp-words
'("alist" "emacs" "etags" "keymap" "paren" "regexp" "sexp")
"List of words that are correct when spell-checking Lisp documentation.")
-;;;###autoload(put 'checkdoc-ispell-list-words 'safe-local-variable #'checkdoc-list-of-strings-p)
+;;;###autoload(put 'checkdoc-ispell-list-words 'safe-local-variable #'list-of-strings-p)
(defcustom checkdoc-max-keyref-before-warn nil
"If non-nil, number of \\\\=[command-to-keystroke] tokens allowed in a doc string.
@@ -320,7 +320,7 @@ These words are ignored when unquoted symbols are searched for.
This should be set in an Emacs Lisp file's local variables."
:type '(repeat (string :tag "Word"))
:version "28.1")
-;;;###autoload(put 'checkdoc-symbol-words 'safe-local-variable #'checkdoc-list-of-strings-p)
+;;;###autoload(put 'checkdoc-symbol-words 'safe-local-variable #'list-of-strings-p)
(defcustom checkdoc-column-zero-backslash-before-paren t
"Non-nil means to warn if there is no \"\\\" before \"(\" in column zero.
@@ -360,9 +360,9 @@ large number of libraries means it is impractical to fix all
of these warnings masse. In almost any other case, setting
this to anything but t is likely to be counter-productive.")
-;;;###autoload
(defun checkdoc-list-of-strings-p (obj)
"Return t when OBJ is a list of strings."
+ (declare (obsolete list-of-strings-p "29.1"))
;; this is a function so it might be shared by checkdoc-proper-noun-list
;; and/or checkdoc-ispell-lisp-words in the future
(and (listp obj)
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 0560ddda268..b3ade3b8943 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -94,11 +94,6 @@
;; This second one is closely related to what we do here (and that's
;; the name "generalizer" comes from).
-;; The autoloads.el mechanism which adds package--builtin-versions
-;; maintenance to loaddefs.el doesn't work for preloaded packages (such
-;; as this one), so we have to do it by hand!
-(push (purecopy '(cl-generic 1 0)) package--builtin-versions)
-
;; Note: For generic functions that dispatch on several arguments (i.e. those
;; which use the multiple-dispatch feature), we always use the same "tagcodes"
;; and the same set of arguments on which to dispatch. This works, but is
@@ -425,11 +420,13 @@ the specializer used will be the one returned by BODY."
;; only called with explicit arguments.
(uses-cnm (macroexp--fgrep `((,cnm) (,nmp)) nbody))
(λ-lift (mapcar #'car uses-cnm)))
- (if (not uses-cnm)
- (cons nil
- `#'(lambda (,@args)
- ,@(car parsed-body)
- ,nbody))
+ (cond
+ ((not uses-cnm)
+ (cons nil
+ `#'(lambda (,@args)
+ ,@(car parsed-body)
+ ,nbody)))
+ (lexical-binding
(cons 'curried
`#'(lambda (,nm) ;Called when constructing the effective method.
(let ((,nmp (if (cl--generic-isnot-nnm-p ,nm)
@@ -465,7 +462,20 @@ the specializer used will be the one returned by BODY."
;; A destructuring-bind would do the trick
;; as well when/if it's more efficient.
(apply (lambda (,@λ-lift ,@args) ,nbody)
- ,@λ-lift ,arglist)))))))))
+ ,@λ-lift ,arglist)))))))
+ (t
+ (cons t
+ `#'(lambda (,cnm ,@args)
+ ,@(car parsed-body)
+ ,(macroexp-warn-and-return
+ "cl-defmethod used without lexical-binding"
+ (if (not (assq nmp uses-cnm))
+ nbody
+ `(let ((,nmp (lambda ()
+ (cl--generic-isnot-nnm-p ,cnm))))
+ ,nbody))
+ 'lexical t)))))
+ ))
(f (error "Unexpected macroexpansion result: %S" f))))))
(put 'cl-defmethod 'function-documentation
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index f8fdc50251f..beafee1d631 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -775,14 +775,34 @@ compared by `eql'.
\(fn EXPR (KEYLIST BODY...)...)"
(declare (indent 1) (debug (form &rest (sexp body))))
(macroexp-let2 macroexp-copyable-p temp expr
- (let* ((head-list nil))
+ (let* ((head-list nil)
+ (has-otherwise nil))
`(cond
,@(mapcar
(lambda (c)
- (cons (cond ((memq (car c) '(t otherwise)) t)
+ (cons (cond (has-otherwise
+ (error "Misplaced t or `otherwise' clause"))
+ ((memq (car c) '(t otherwise))
+ (setq has-otherwise t)
+ t)
((eq (car c) 'cl--ecase-error-flag)
`(error "cl-ecase failed: %s, %s"
,temp ',(reverse head-list)))
+ ((null (car c))
+ (macroexp-warn-and-return
+ "Case nil will never match"
+ nil 'suspicious))
+ ((and (consp (car c)) (cdar c) (not (cddar c))
+ (memq (caar c) '(quote function)))
+ (macroexp-warn-and-return
+ (format-message
+ (concat "Case %s will match `%s'. If "
+ "that's intended, write %s "
+ "instead. Otherwise, don't "
+ "quote `%s'.")
+ (car c) (caar c) (list (cadar c) (caar c))
+ (cadar c))
+ `(cl-member ,temp ',(car c)) 'suspicious))
((listp (car c))
(setq head-list (append (car c) head-list))
`(cl-member ,temp ',(car c)))
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index a9087313b18..889bffa3f5c 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -178,14 +178,15 @@ and above."
:type '(repeat string)
:version "28.1")
-(defcustom native-comp-driver-options nil
+(defcustom native-comp-driver-options (when (eq system-type 'darwin)
+ '("-Wl,-w"))
"Options passed verbatim to the native compiler's back-end driver.
Note that not all options are meaningful; typically only the options
affecting the assembler and linker are likely to be useful.
Passing these options is only available in libgccjit version 9
and above."
- :type '(repeat string) ; FIXME is this right?
+ :type '(repeat string)
:version "28.1")
(defcustom comp-libgccjit-reproducer nil
@@ -3800,22 +3801,25 @@ Return the trampoline if found or nil otherwise."
(lexical-binding t))
(comp--native-compile
form nil
- (cl-loop
- for dir in (if native-compile-target-directory
- (list (expand-file-name comp-native-version-dir
- native-compile-target-directory))
- (comp-eln-load-path-eff))
- for f = (expand-file-name
- (comp-trampoline-filename subr-name)
- dir)
- unless (file-exists-p dir)
- do (ignore-errors
- (make-directory dir t)
- (cl-return f))
- when (file-writable-p f)
- do (cl-return f)
- finally (error "Cannot find suitable directory for output in \
-`native-comp-eln-load-path'")))))
+ ;; If we've disabled nativecomp, don't write the trampolines to
+ ;; the eln cache (but create them).
+ (and (not inhibit-automatic-native-compilation)
+ (cl-loop
+ for dir in (if native-compile-target-directory
+ (list (expand-file-name comp-native-version-dir
+ native-compile-target-directory))
+ (comp-eln-load-path-eff))
+ for f = (expand-file-name
+ (comp-trampoline-filename subr-name)
+ dir)
+ unless (file-exists-p dir)
+ do (ignore-errors
+ (make-directory dir t)
+ (cl-return f))
+ when (file-writable-p f)
+ do (cl-return f)
+ finally (error "Cannot find suitable directory for output in \
+`native-comp-eln-load-path'"))))))
;; Some entry point support code.
@@ -4044,7 +4048,6 @@ the deferred compilation mechanism."
(list "Not a function symbol or file" function-or-file)))
(catch 'no-native-compile
(let* ((print-symbols-bare t)
- (max-specpdl-size (max max-specpdl-size 5000))
(data function-or-file)
(comp-native-compiling t)
(byte-native-qualities nil)
@@ -4107,6 +4110,7 @@ the deferred compilation mechanism."
comp-ctxt
(comp-ctxt-output comp-ctxt)
(file-exists-p (comp-ctxt-output comp-ctxt)))
+ (message "Deleting %s" (comp-ctxt-output comp-ctxt))
(delete-file (comp-ctxt-output comp-ctxt)))))))
(defun native-compile-async-skip-p (file load selector)
@@ -4200,6 +4204,17 @@ bytecode definition was not changed in the meantime)."
;;; Compiler entry points.
+(defun comp-compile-all-trampolines ()
+ "Pre-compile AOT all trampolines."
+ (let ((comp-running-batch-compilation t)
+ ;; We want to target only the 'native-lisp' directory.
+ (native-compile-target-directory
+ (car (last native-comp-eln-load-path))))
+ (mapatoms (lambda (f)
+ (when (subr-primitive-p (symbol-function f))
+ (message "Compiling trampoline for: %s" f)
+ (comp-trampoline-compile f))))))
+
;;;###autoload
(defun comp-lookup-eln (filename)
"Given a Lisp source FILENAME return the corresponding .eln file if found.
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index 460057b3afd..f78d44cf98e 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -110,10 +110,6 @@ The value used here is passed to `quit-restore-window'."
(defvar debugger-previous-window-height nil
"The last recorded height of `debugger-previous-window'.")
-(defvar debugger-previous-backtrace nil
- "The contents of the previous backtrace (including text properties).
-This is to optimize `debugger-make-xrefs'.")
-
(defvar debugger-outer-match-data)
(defvar debugger-will-be-back nil
"Non-nil if we expect to get back in the debugger soon.")
@@ -836,6 +832,10 @@ To specify a nil argument interactively, exit with an empty minibuffer."
;;;###autoload
(defalias 'cancel-debug-watch #'cancel-debug-on-variable-change)
+(make-obsolete-variable 'debugger-previous-backtrace
+ "no longer used." "29.1")
+(defvar debugger-previous-backtrace nil)
+
(provide 'debug)
;;; debug.el ends here
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 31c05057bfa..67704bdb51c 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -129,7 +129,7 @@ contains an infinite loop. When Edebug is instrumenting code
containing very large quoted lists, it may reach this limit and give
the error message \"Too deep - perhaps infinite loop in spec?\".
Make this limit larger to countermand that, but you may also need to
-increase `max-lisp-eval-depth' and `max-specpdl-size'."
+increase `max-lisp-eval-depth'."
:type 'integer
:version "26.1")
@@ -1107,8 +1107,7 @@ purpose by adding an entry to this alist, and setting
edebug-best-error
edebug-error-point
;; Do this once here instead of several times.
- (max-lisp-eval-depth (+ 800 max-lisp-eval-depth))
- (max-specpdl-size (+ 2000 max-specpdl-size)))
+ (max-lisp-eval-depth (+ 800 max-lisp-eval-depth)))
(let ((no-match
(catch 'no-match
(setq result (edebug-read-and-maybe-wrap-form1))
@@ -2317,7 +2316,6 @@ and run its entry function, and set up `edebug-before' and
;; but not inside an unwind-protect.
;; Doing it here also keeps it from growing too large.
(max-lisp-eval-depth (+ 100 max-lisp-eval-depth)) ; too much??
- (max-specpdl-size (+ 200 max-specpdl-size))
(debugger edebug-debugger) ; only while edebug is active.
(edebug-outside-debug-on-error debug-on-error)
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index 5e7b5cbfb2f..65aa6aa6df7 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -249,16 +249,22 @@ use '%s or turn off `eieio-backward-compatibility' instead" cname)
(defun eieio-make-class-predicate (class)
(lambda (obj)
(:documentation
- (format "Return non-nil if OBJ is an object of type `%S'.\n\n(fn OBJ)"
- class))
+ (concat
+ (internal--format-docstring-line
+ "Return non-nil if OBJ is an object of type `%S'."
+ class)
+ "\n\n(fn OBJ)"))
(and (eieio-object-p obj)
(same-class-p obj class))))
(defun eieio-make-child-predicate (class)
(lambda (obj)
(:documentation
- (format "Return non-nil if OBJ is an object of type `%S' or a subclass.
-\n(fn OBJ)" class))
+ (concat
+ (internal--format-docstring-line
+ "Return non-nil if OBJ is an object of type `%S' or a subclass."
+ class)
+ "\n\n(fn OBJ)"))
(and (eieio-object-p obj)
(object-of-class-p obj class))))
@@ -353,8 +359,8 @@ See `defclass' for more information."
(defalias csym
(lambda (obj)
(:documentation
- (format
- "Test OBJ to see if it a list of objects which are a child of type %s"
+ (internal--format-docstring-line
+ "Test OBJ to see if it a list of objects which are a child of type `%s'."
cname))
(when (listp obj)
(let ((ans t)) ;; nil is valid
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index 984166b593a..8351d97b13d 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -136,6 +136,7 @@ and reference them using the function `class-option'."
(accessors ()))
;; Collect the accessors we need to define.
+ (setq slots (mapcar (lambda (x) (if (consp x) x (list x))) slots))
(pcase-dolist (`(,sname . ,soptions) slots)
(let* ((acces (plist-get soptions :accessor))
(initarg (plist-get soptions :initarg))
@@ -217,10 +218,11 @@ and reference them using the function `class-option'."
(when (and eieio-backward-compatibility (eq alloc :class))
;; FIXME: How could I declare this *method* as obsolete.
(push `(cl-defmethod ,acces ((this (subclass ,name)))
- ,(format
- "Retrieve the class slot `%S' from a class `%S'.
-This method is obsolete."
- sname name)
+ ,(concat
+ (internal--format-docstring-line
+ "Retrieve the class slot `%S' from a class `%S'."
+ sname name)
+ "\nThis method is obsolete.")
(if (slot-boundp this ',sname)
(eieio-oref-default this ',sname)))
accessors)))
@@ -229,16 +231,18 @@ This method is obsolete."
;; name whose purpose is to set the value of the slot.
(if writer
(push `(cl-defmethod ,writer ((this ,name) value)
- ,(format "Set the slot `%S' of an object of class `%S'."
- sname name)
+ ,(internal--format-docstring-line
+ "Set the slot `%S' of an object of class `%S'."
+ sname name)
(setf (slot-value this ',sname) value))
accessors))
;; If a reader is defined, then create a generic method
;; of that name whose purpose is to access this slot value.
(if reader
(push `(cl-defmethod ,reader ((this ,name))
- ,(format "Access the slot `%S' from object of class `%S'."
- sname name)
+ ,(internal--format-docstring-line
+ "Access the slot `%S' from object of class `%S'."
+ sname name)
(slot-value this ',sname))
accessors))
))
diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el
index fe291290a28..a891f068a70 100644
--- a/lisp/emacs-lisp/ert-x.el
+++ b/lisp/emacs-lisp/ert-x.el
@@ -126,7 +126,15 @@ value is the last form in BODY."
(body-function
. ,(lambda (window)
(select-window window t)
- (let ((inhibit-modification-hooks nil))
+ ;; body-function is intended to initialize the
+ ;; contents of a temporary read-only buffer, so
+ ;; it is executed with some convenience
+ ;; changes. Undo those changes so that the
+ ;; test buffer behaves more like an ordinary
+ ;; buffer while the body executes.
+ (let ((inhibit-modification-hooks nil)
+ (inhibit-read-only nil)
+ (buffer-read-only nil))
(setq ,ret (progn ,@body))))))
nil))
,ret))))
@@ -451,6 +459,10 @@ The following keyword arguments are supported:
:text STRING If non-nil, pass STRING to `make-temp-file' as
the TEXT argument.
+:buffer SYMBOL Open the temporary file using `find-file-noselect'
+ and bind SYMBOL to the buffer. Kill the buffer
+ after BODY exits normally or non-locally.
+
:coding CODING If non-nil, bind `coding-system-for-write' to CODING
when executing BODY. This is handy when STRING includes
non-ASCII characters or the temporary file must have a
@@ -459,14 +471,17 @@ The following keyword arguments are supported:
See also `ert-with-temp-directory'."
(declare (indent 1) (debug (symbolp body)))
(cl-check-type name symbol)
- (let (keyw prefix suffix directory text extra-keywords coding)
+ (let (keyw prefix suffix directory text extra-keywords buffer coding)
(while (keywordp (setq keyw (car body)))
(setq body (cdr body))
(pcase keyw
(:prefix (setq prefix (pop body)))
(:suffix (setq suffix (pop body)))
+ ;; This is only for internal use by `ert-with-temp-directory'
+ ;; and is therefore not documented.
(:directory (setq directory (pop body)))
(:text (setq text (pop body)))
+ (:buffer (setq buffer (pop body)))
(:coding (setq coding (pop body)))
(_ (push keyw extra-keywords) (pop body))))
(when extra-keywords
@@ -481,10 +496,17 @@ See also `ert-with-temp-directory'."
(make-temp-file ,prefix ,directory ,suffix ,text)))
(,name ,(if directory
`(file-name-as-directory ,temp-file)
- temp-file)))
+ temp-file))
+ ,@(when buffer
+ (list `(,buffer (find-file-literally ,temp-file)))))
(unwind-protect
(progn ,@body)
(ignore-errors
+ ,@(when buffer
+ (list `(with-current-buffer buf
+ (set-buffer-modified-p nil))
+ `(kill-buffer ,buffer))))
+ (ignore-errors
,(if directory
`(delete-directory ,temp-file :recursive)
`(delete-file ,temp-file))))))))
@@ -546,7 +568,7 @@ The same keyword arguments are supported as in
`("\\`mock\\'" nil ,(system-name)))
;; Emacs's Makefile sets $HOME to a nonexistent value. Needed
;; in batch mode only, therefore.
- (unless (and (null noninteractive) (file-directory-p "~/"))
+ (when (and noninteractive (not (file-directory-p "~/")))
(setenv "HOME" temporary-file-directory))
(format "/mock::%s" temporary-file-directory))))
"Temporary directory for remote file tests.")
diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el
index 1db9d96d999..a96fa19a3ff 100644
--- a/lisp/emacs-lisp/gv.el
+++ b/lisp/emacs-lisp/gv.el
@@ -536,13 +536,15 @@ The return value is the last VAL in the list.
(funcall do `(error . ,args)
(lambda (v) `(progn ,v (error . ,args))))))
-(defmacro gv-synthetic-place (getter setter)
+(defun gv-synthetic-place (getter setter)
"Special place described by its setter and getter.
GETTER and SETTER (typically obtained via `gv-letplace') get and
-set that place. I.e. This macro allows you to do the \"reverse\" of what
-`gv-letplace' does.
-This macro only makes sense when used in a place."
- (declare (gv-expander funcall))
+set that place. I.e. this function allows you to do the
+\"reverse\" of what `gv-letplace' does.
+
+This function is only useful when used in conjunction with
+generalized variables in place forms."
+ (declare (gv-expander funcall) (compiler-macro (lambda (_) getter)))
(ignore setter)
getter)
@@ -810,6 +812,7 @@ REF must have been previously obtained with `gv-ref'."
`(cond
(,v ,(funcall setter val))
((eq ,getter ,val) ,(funcall setter `(not ,val))))))))))
+(make-obsolete-generalized-variable 'eq nil "29.1")
(gv-define-expander substring
(lambda (do place from &optional to)
diff --git a/lisp/emacs-lisp/icons.el b/lisp/emacs-lisp/icons.el
index 93749a3451e..a08ac7463ce 100644
--- a/lisp/emacs-lisp/icons.el
+++ b/lisp/emacs-lisp/icons.el
@@ -202,7 +202,11 @@ present if the icon is represented by an image."
:height (if (eq height 'line)
(window-default-line-height)
height)
- :scale 1)
+ :scale 1
+ :rotation (or (plist-get keywords :rotation) 0)
+ :ascent (if (plist-member keywords :ascent)
+ (plist-get keywords :ascent)
+ 'center))
(create-image file))))))
(cl-defmethod icons--create ((_type (eql 'emoji)) icon _keywords)
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index c906ee6e31d..7e39a77aed5 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -325,6 +325,20 @@ This will generate compile-time constants from BINDINGS."
(throw 'matched t)))
(throw 'matched nil)))))
+(defun lisp-mode--search-key (char bound)
+ (catch 'found
+ (while (re-search-forward
+ (concat "\\_<" char (rx lisp-mode-symbol) "\\_>")
+ bound t)
+ (when (or (< (match-beginning 0) (+ (point-min) 2))
+ ;; A quoted white space before the &/: means that this
+ ;; is not the start of a :keyword or an &option.
+ (not (eql (char-after (- (match-beginning 0) 2))
+ ?\\))
+ (not (memq (char-after (- (match-beginning 0) 1))
+ '(?\s ?\n ?\t))))
+ (throw 'found t)))))
+
(let-when-compile
((lisp-fdefs '("defmacro" "defun"))
(lisp-vdefs '("defvar"))
@@ -496,11 +510,11 @@ This will generate compile-time constants from BINDINGS."
(,(rx "\\\\=")
(0 font-lock-builtin-face prepend))
;; Constant values.
- (,(concat "\\_<:" (rx lisp-mode-symbol) "\\_>")
+ (,(lambda (bound) (lisp-mode--search-key ":" bound))
(0 font-lock-builtin-face))
;; ELisp and CLisp `&' keywords as types.
- (,(concat "\\_<&" (rx lisp-mode-symbol) "\\_>")
- . font-lock-type-face)
+ (,(lambda (bound) (lisp-mode--search-key "&" bound))
+ (0 font-lock-builtin-face))
;; ELisp regexp grouping constructs
(,(lambda (bound)
(catch 'found
@@ -549,11 +563,12 @@ This will generate compile-time constants from BINDINGS."
;; must come before keywords below to have effect
(,(concat "#:" (rx lisp-mode-symbol) "") 0 font-lock-builtin-face)
;; Constant values.
- (,(concat "\\_<:" (rx lisp-mode-symbol) "\\_>")
+ (,(lambda (bound) (lisp-mode--search-key ":" bound))
(0 font-lock-builtin-face))
;; ELisp and CLisp `&' keywords as types.
- (,(concat "\\_<&" (rx lisp-mode-symbol) "\\_>")
- . font-lock-type-face)
+ (,(lambda (bound) (lisp-mode--search-key "&" bound))
+ (0 font-lock-builtin-face))
+ ;; ELisp regexp grouping constructs
;; This is too general -- rms.
;; A user complained that he has functions whose names start with `do'
;; and that they get the wrong color.
diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el
index 005a46c2d75..a1c4f91579e 100644
--- a/lisp/emacs-lisp/loaddefs-gen.el
+++ b/lisp/emacs-lisp/loaddefs-gen.el
@@ -283,14 +283,24 @@ expression, in which case we want to handle forms differently."
,@(when-let ((safe (plist-get props :safe)))
`((put ',varname 'safe-local-variable ,safe))))))
+ ;; Extract theme properties.
+ ((eq car 'deftheme)
+ (let* ((name (car-safe (cdr-safe form)))
+ (props (nthcdr 3 form)))
+ `(put ',name 'theme-properties (list ,@props))))
+
((eq car 'defgroup)
;; In Emacs this is normally handled separately by cus-dep.el, but for
;; third party packages, it can be convenient to explicitly autoload
;; a group.
- (let ((groupname (nth 1 form)))
+ (let ((groupname (nth 1 form))
+ (parent (eval (plist-get form :group) t)))
`(let ((loads (get ',groupname 'custom-loads)))
(if (member ',file loads) nil
- (put ',groupname 'custom-loads (cons ',file loads))))))
+ (put ',groupname 'custom-loads (cons ',file loads))
+ ,@(when parent
+ `((put ',parent 'custom-loads
+ (cons ',groupname (get ',parent 'custom-loads)))))))))
;; When processing a macro expansion, any expression
;; before a :autoload-end should be included. These are typically (put
@@ -512,7 +522,7 @@ If COMPILE, don't include a \"don't compile\" cookie."
(defun loaddefs-generate (dir output-file &optional excluded-files
extra-data include-package-version
generate-full)
- "Generate loaddefs files for Lisp files in the directories DIRS.
+ "Generate loaddefs files for Lisp files in one or more directories given by DIR.
DIR can be either a single directory or a list of directories.
The autoloads will be written to OUTPUT-FILE. If any Lisp file
@@ -520,7 +530,7 @@ binds `generated-autoload-file' as a file-local variable, write
its autoloads into the specified file instead.
The function does NOT recursively descend into subdirectories of the
-directory or directories specified by DIRS.
+directories specified by DIR.
Optional argument EXCLUDED-FILES, if non-nil, should be a list of
files, such as preloaded files, whose autoloads should not be written
@@ -628,7 +638,7 @@ instead of just updating them with the new/changed autoloads."
;; It's a new file; put the data at the end.
(progn
(goto-char (point-max))
- (search-backward "\f\n"))
+ (search-backward "\f\n" nil t))
;; Delete the old version of the section.
(delete-region (match-beginning 0)
(and (search-forward "\n\f\n;;;")
@@ -726,7 +736,14 @@ rules for built-in packages and excluded files."
;; updated.
(file-newer-than-file-p
(expand-file-name "emacs-lisp/loaddefs-gen.el" lisp-directory)
- output-file))))
+ output-file)))
+ (let ((lisp-mode-autoload-regexp
+ "^;;;###\\(\\(noexist\\)-\\)?\\(theme-autoload\\)"))
+ (loaddefs-generate
+ (expand-file-name "../etc/themes/" lisp-directory)
+ (expand-file-name "theme-loaddefs.el" lisp-directory))))
+
+;;;###autoload (load "theme-loaddefs.el")
(provide 'loaddefs-gen)
diff --git a/lisp/emacs-lisp/memory-report.el b/lisp/emacs-lisp/memory-report.el
index 56b1ea6ed48..968a80b59e7 100644
--- a/lisp/emacs-lisp/memory-report.el
+++ b/lisp/emacs-lisp/memory-report.el
@@ -262,12 +262,7 @@ by counted more than once."
(cl-struct-slot-info struct-type)))))
(defun memory-report--format (bytes)
- (setq bytes (/ bytes 1024.0))
- (let ((units '("KiB" "MiB" "GiB" "TiB")))
- (while (>= bytes 1024)
- (setq bytes (/ bytes 1024.0))
- (setq units (cdr units)))
- (format "%6.1f %s" bytes (car units))))
+ (format "%10s" (file-size-human-readable bytes 'iec " ")))
(defun memory-report--gc-elem (elems type)
(* (nth 1 (assq type elems))
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
index a9a20ab5abf..429052bfdf3 100644
--- a/lisp/emacs-lisp/nadvice.el
+++ b/lisp/emacs-lisp/nadvice.el
@@ -4,6 +4,7 @@
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
;; Keywords: extensions, lisp, tools
+;; Version: 1.0
;; This file is part of GNU Emacs.
@@ -37,11 +38,6 @@
;;; Code:
-;; The autoloads.el mechanism which adds package--builtin-versions
-;; maintenance to loaddefs.el doesn't work for preloaded packages (such
-;; as this one), so we have to do it by hand!
-(push (purecopy '(nadvice 1 0)) package--builtin-versions)
-
(oclosure-define (advice
(:predicate advice--p)
(:copier advice--cons (cdr))
@@ -108,19 +104,26 @@ DOC is a string where \"FUNCTION\" and \"OLDFUN\" are expected.")
(format "%s\n%s" name doc)
(format "%s" name))
(or doc "No documentation")))))
- "\n")))
+ "\n"
+ (and
+ (eq how :override)
+ (concat
+ (format-message
+ "\nThis is an :override advice, which means that `%s' isn't\n" function)
+ "run at all, and the documentation below may be irrelevant.\n")))))
(defun advice--make-docstring (function)
"Build the raw docstring for FUNCTION, presumably advised."
(let* ((flist (indirect-function function))
(docfun nil)
(macrop (eq 'macro (car-safe flist)))
- (docstring nil))
+ (before nil)
+ (after nil))
(when macrop
(setq flist (cdr flist)))
(if (and (autoloadp flist)
(get function 'advice--pending))
- (setq docstring
+ (setq after
(advice--make-single-doc (get function 'advice--pending)
function macrop))
(while (advice--p flist)
@@ -130,9 +133,13 @@ DOC is a string where \"FUNCTION\" and \"OLDFUN\" are expected.")
;; object instead! So here we try to undo the damage.
(when (integerp (aref flist 4))
(setq docfun flist))
- (setq docstring (concat docstring (advice--make-single-doc
- flist function macrop))
- flist (advice--cdr flist))))
+ (let ((doc-bit (advice--make-single-doc flist function macrop)))
+ ;; We want :overrides to go to the front, because they mean
+ ;; that the doc string may be irrelevant.
+ (if (eq (advice--how flist) :override)
+ (setq before (concat before doc-bit))
+ (setq after (concat after doc-bit))))
+ (setq flist (advice--cdr flist))))
(unless docfun
(setq docfun flist))
(let* ((origdoc (unless (eq function docfun) ;Avoid inf-loops.
@@ -145,12 +152,18 @@ DOC is a string where \"FUNCTION\" and \"OLDFUN\" are expected.")
(if (stringp arglist) t
(help--make-usage-docstring function arglist)))
(setq origdoc (cdr usage)) (car usage)))
- (help-add-fundoc-usage (concat origdoc
- (if (string-suffix-p "\n" origdoc)
- "\n"
- "\n\n")
- docstring)
- usage))))
+ (help-add-fundoc-usage
+ (with-temp-buffer
+ (when before
+ (insert before)
+ (ensure-empty-lines 1))
+ (when origdoc
+ (insert origdoc))
+ (when after
+ (ensure-empty-lines 1)
+ (insert after))
+ (buffer-string))
+ usage))))
(defun advice-eval-interactive-spec (spec)
"Evaluate the interactive spec SPEC."
diff --git a/lisp/emacs-lisp/oclosure.el b/lisp/emacs-lisp/oclosure.el
index 9775e8cc656..c77ac151d77 100644
--- a/lisp/emacs-lisp/oclosure.el
+++ b/lisp/emacs-lisp/oclosure.el
@@ -557,6 +557,21 @@ This has 2 uses:
(oclosure-define (save-some-buffers-function
(:predicate save-some-buffers-function--p)))
+;; This OClosure type is used internally by `cconv.el' to handle
+;; the case where we need to build a closure whose `interactive' spec
+;; captures variables from the context.
+;; It arguably belongs with `cconv.el' but is needed at runtime,
+;; so we placed it here.
+(oclosure-define (cconv--interactive-helper) fun if)
+(defun cconv--interactive-helper (fun if)
+ "Add interactive \"form\" IF to FUN.
+Returns a new command that otherwise behaves like FUN.
+IF should actually not be a form but a function of no arguments."
+ (oclosure-lambda (cconv--interactive-helper (fun fun) (if if))
+ (&rest args)
+ (apply (if (called-interactively-p 'any)
+ #'funcall-interactively #'funcall)
+ fun args)))
(provide 'oclosure)
;;; oclosure.el ends here
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 634178c7810..d464e120193 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -347,21 +347,28 @@ default directory."
(defcustom package-check-signature 'allow-unsigned
"Non-nil means to check package signatures when installing.
-More specifically the value can be:
-- nil: package signatures are ignored.
-- `allow-unsigned': install a package even if it is unsigned, but
- if it is signed, we have the key for it, and OpenGPG is
- installed, verify the signature.
-- t: accept a package only if it comes with at least one verified signature.
-- `all': same as t, except when the package has several signatures,
- in which case we verify all the signatures.
This also applies to the \"archive-contents\" file that lists the
-contents of the archive."
+contents of the archive.
+
+The value can be one of:
+
+ t Accept a package only if it comes with at least
+ one verified signature.
+
+ `all' Same as t, but verify all signatures if there
+ are more than one.
+
+ `allow-unsigned' Install a package even if it is unsigned,
+ but verify the signature if possible (that
+ is, if it is signed, we have the key for it,
+ and GnuPG is installed).
+
+ nil Package signatures are ignored."
:type '(choice (const :value nil :tag "Never")
(const :value allow-unsigned :tag "Allow unsigned")
(const :value t :tag "Check always")
- (const :value all :tag "Check all signatures"))
+ (const :value all :tag "Check always (all signatures)"))
:risky t
:version "27.1")
@@ -924,7 +931,7 @@ untar into a directory named DIR; otherwise, signal an error."
(or (string-match regexp name)
;; Tarballs created by some utilities don't list
;; directories with a trailing slash (Bug#13136).
- (and (string-equal dir name)
+ (and (string-equal (expand-file-name dir) name)
(eq (tar-header-link-type tar-data) 5))
(error "Package does not untar cleanly into directory %s/" dir)))))
(tar-untar-buffer))
@@ -1186,8 +1193,12 @@ Return the pkg-desc, with desc-kind set to KIND."
"Find package information for a tar file.
The return result is a `package-desc'."
(cl-assert (derived-mode-p 'tar-mode))
- (let* ((dir-name (file-name-directory
- (tar-header-name (car tar-parse-info))))
+ (let* ((dir-name (named-let loop
+ ((filename (tar-header-name (car tar-parse-info))))
+ (let ((dirname (file-name-directory filename)))
+ ;; The first file can be in a subdir: look for the top.
+ (if dirname (loop (directory-file-name dirname))
+ (file-name-as-directory filename)))))
(desc-file (package--description-file dir-name))
(tar-desc (tar-get-file-descriptor (concat dir-name desc-file))))
(unless tar-desc
@@ -2190,8 +2201,8 @@ to install it but still mark it as selected."
(assq (car elt) package-archive-contents)))
(and available
(version-list-<
- (package-desc-priority-version (cadr elt))
- (package-desc-priority-version (cadr available))))))
+ (package-desc-version (cadr elt))
+ (package-desc-version (cadr available))))))
package-alist)))
;;;###autoload
@@ -2437,10 +2448,14 @@ If NOSAVE is non-nil, the package is not removed from
"Reinstall package PKG.
PKG should be either a symbol, the package name, or a `package-desc'
object."
- (interactive (list (intern (completing-read
- "Reinstall package: "
- (mapcar #'symbol-name
- (mapcar #'car package-alist))))))
+ (interactive
+ (progn
+ (package--archives-initialize)
+ (list (intern (completing-read
+ "Reinstall package: "
+ (mapcar #'symbol-name
+ (mapcar #'car package-alist)))))))
+ (package--archives-initialize)
(package-delete
(if (package-desc-p pkg) pkg (cadr (assq pkg package-alist)))
'force 'nosave)
diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el
index cae5dd00d1d..4d5a39458d2 100644
--- a/lisp/emacs-lisp/regexp-opt.el
+++ b/lisp/emacs-lisp/regexp-opt.el
@@ -133,7 +133,6 @@ usually more efficient than that of a simplified version:
(save-match-data
;; Recurse on the sorted list.
(let* ((max-lisp-eval-depth 10000)
- (max-specpdl-size 10000)
(completion-ignore-case nil)
(completion-regexp-list nil)
(open (cond ((stringp paren) paren) (paren "\\(")))
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 31dcfa98b40..82ade0ac0c3 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -695,5 +695,9 @@ which may be shorter."
result))
(nreverse result)))
+(defun seq-keep (function sequence)
+ "Apply FUNCTION to SEQUENCE and return all non-nil results."
+ (delq nil (seq-map function sequence)))
+
(provide 'seq)
;;; seq.el ends here
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index 2472479bad6..dbac03432c1 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -22,6 +22,15 @@
;;; Commentary:
+;; This package lists functions based on various groupings.
+;;
+;; For instance, `string-trim' and `mapconcat' are `string' functions,
+;; so `M-x shortdoc RET string RET' will give an overview of functions
+;; that operate on strings.
+;;
+;; The documentation groups are created with the
+;; `define-short-documentation-group' macro.
+
;;; Code:
(require 'seq)
@@ -355,13 +364,11 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'),
(abbreviate-file-name
:no-eval (abbreviate-file-name "/home/some-user")
:eg-result "~some-user")
- (file-parent-directory
- :eval (file-parent-directory "/foo/bar")
- :eval (file-parent-directory "~")
- :eval (file-parent-directory "/tmp/")
- :eval (file-parent-directory "foo/bar")
- :eval (file-parent-directory "foo")
- :eval (file-parent-directory "/"))
+ (file-name-parent-directory
+ :eval (file-name-parent-directory "/foo/bar")
+ :eval (file-name-parent-directory "/foo/")
+ :eval (file-name-parent-directory "foo/bar")
+ :eval (file-name-parent-directory "foo"))
"Quoted File Names"
(file-name-quote
:args (name)
@@ -890,6 +897,8 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'),
:eval (seq-drop-while #'numberp '(1 2 c d 5)))
(seq-filter
:eval (seq-filter #'numberp '(a b 3 4 f 6)))
+ (seq-keep
+ :eval (seq-keep #'cl-digit-char-p '(?6 ?a ?7)))
(seq-remove
:eval (seq-remove #'numberp '(1 2 c d 5)))
(seq-remove-at-position
@@ -1514,8 +1523,11 @@ Example:
:doc "Keymap for `shortdoc-mode'."
"n" #'shortdoc-next
"p" #'shortdoc-previous
+ "N" #'shortdoc-next-section
+ "P" #'shortdoc-previous-section
"C-c C-n" #'shortdoc-next-section
- "C-c C-p" #'shortdoc-previous-section)
+ "C-c C-p" #'shortdoc-previous-section
+ "w" #'shortdoc-copy-function-as-kill)
(define-derived-mode shortdoc-mode special-mode "shortdoc"
"Mode for shortdoc."
@@ -1528,35 +1540,49 @@ Example:
(funcall
(if reverse 'text-property-search-backward
'text-property-search-forward)
- sym nil t t)
+ sym nil t)
(setq arg (1- arg))))
(defun shortdoc-next (&optional arg)
- "Move cursor to the next function.
-With ARG, do it that many times."
+ "Move point to the next function.
+With prefix numeric argument ARG, do it that many times."
(interactive "p" shortdoc-mode)
(shortdoc--goto-section arg 'shortdoc-function))
(defun shortdoc-previous (&optional arg)
- "Move cursor to the previous function.
-With ARG, do it that many times."
+ "Move point to the previous function.
+With prefix numeric argument ARG, do it that many times."
(interactive "p" shortdoc-mode)
(shortdoc--goto-section arg 'shortdoc-function t)
(backward-char 1))
(defun shortdoc-next-section (&optional arg)
- "Move cursor to the next section.
-With ARG, do it that many times."
+ "Move point to the next section.
+With prefix numeric argument ARG, do it that many times."
(interactive "p" shortdoc-mode)
(shortdoc--goto-section arg 'shortdoc-section))
(defun shortdoc-previous-section (&optional arg)
- "Move cursor to the previous section.
-With ARG, do it that many times."
+ "Move point to the previous section.
+With prefix numeric argument ARG, do it that many times."
(interactive "p" shortdoc-mode)
(shortdoc--goto-section arg 'shortdoc-section t)
(forward-line -2))
+(defun shortdoc-copy-function-as-kill ()
+ "Copy name of the function near point into the kill ring."
+ (interactive)
+ (save-excursion
+ (goto-char (pos-bol))
+ (when-let* ((re (rx bol "(" (group (+ (not (in " "))))))
+ (string
+ (and (or (looking-at re)
+ (re-search-backward re nil t))
+ (match-string 1))))
+ (set-text-properties 0 (length string) nil string)
+ (kill-new string)
+ (message string))))
+
(provide 'shortdoc)
;;; shortdoc.el ends here
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index bd7c3c82f97..6e4d88b4df3 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -97,6 +97,7 @@ threading."
(maphash (lambda (_ v) (push v values)) hash-table)
values))
+;;;###autoload
(defsubst string-join (strings &optional separator)
"Join all STRINGS using SEPARATOR.
Optional argument SEPARATOR must be a string, a vector, or a list of
diff --git a/lisp/emacs-lisp/testcover.el b/lisp/emacs-lisp/testcover.el
index cd2e388ce42..760063d1f9d 100644
--- a/lisp/emacs-lisp/testcover.el
+++ b/lisp/emacs-lisp/testcover.el
@@ -637,8 +637,7 @@ argument is maybe, return maybe. Return 1value only if both arguments
are 1value."
(cl-case val
(testcover-1value result)
- (maybe (and result 'maybe))
- (nil nil)))
+ (maybe (and result 'maybe))))
(defun testcover-analyze-coverage-compose (forms func)
"Analyze a list of FORMS for code coverage using FUNC.
diff --git a/lisp/emacs-lisp/vtable.el b/lisp/emacs-lisp/vtable.el
index 61265c97c28..de8503a1cb1 100644
--- a/lisp/emacs-lisp/vtable.el
+++ b/lisp/emacs-lisp/vtable.el
@@ -353,6 +353,11 @@ This also updates the displayed table."
(let* ((cache (vtable--cache table))
(inhibit-read-only t)
(keymap (get-text-property (point) 'keymap))
+ (ellipsis (if (vtable-ellipsis table)
+ (propertize (truncate-string-ellipsis)
+ 'face (vtable-face table))
+ ""))
+ (ellipsis-width (string-pixel-width ellipsis))
(elem (and after-object
(assq after-object (car cache))))
(line (cons object (vtable--compute-cached-line table object))))
@@ -370,7 +375,8 @@ This also updates the displayed table."
;; FIXME: We have to adjust colors in lines below this if we
;; have :row-colors.
(vtable--insert-line table line 0
- (nth 1 cache) (vtable--spacer table))
+ (nth 1 cache) (vtable--spacer table)
+ ellipsis ellipsis-width)
(add-text-properties start (point) (list 'keymap keymap
'vtable table)))
;; We may have inserted a non-numerical value into a previously
@@ -516,7 +522,8 @@ This also updates the displayed table."
(if (> (nth 1 elem) (elt widths index))
(concat
(vtable--limit-string
- pre-computed (- (elt widths index) ellipsis-width))
+ pre-computed (- (elt widths index)
+ (or ellipsis-width 0)))
ellipsis)
pre-computed))
;; Recompute widths.
@@ -524,7 +531,8 @@ This also updates the displayed table."
(if (> (string-pixel-width value) (elt widths index))
(concat
(vtable--limit-string
- value (- (elt widths index) ellipsis-width))
+ value (- (elt widths index)
+ (or ellipsis-width 0)))
ellipsis)
value))))
(start (point))
@@ -770,7 +778,8 @@ If NEXT, do the next column."
((string-match "\\([0-9.]+\\)px" spec)
(string-to-number (match-string 1 spec)))
((string-match "\\([0-9.]+\\)%" spec)
- (* (string-to-number (match-string 1 spec)) (window-width nil t)))
+ (/ (* (string-to-number (match-string 1 spec)) (window-width nil t))
+ 100))
(t
(error "Invalid spec: %s" spec))))
diff --git a/lisp/epa-hook.el b/lisp/epa-hook.el
index 18e47c682e8..386bd739640 100644
--- a/lisp/epa-hook.el
+++ b/lisp/epa-hook.el
@@ -88,6 +88,14 @@ interface, update `file-name-handler-alist'."
epa-file-inhibit-auto-save)
(auto-save-mode 0)))
+(defun epa-file-name-p (file)
+ "Say whether FILE is handled by `epa-file'."
+ (and auto-encryption-mode (string-match-p epa-file-name-regexp file)))
+
+(with-eval-after-load 'bookmark
+ (add-hook 'bookmark-inhibit-context-functions
+ #'epa-file-name-p))
+
(define-minor-mode auto-encryption-mode
"Toggle automatic file encryption/decryption (Auto Encryption mode)."
:global t :init-value t :group 'epa-file :version "23.1"
diff --git a/lisp/epa-ks.el b/lisp/epa-ks.el
index 7c60b659f0a..4c539b56a37 100644
--- a/lisp/epa-ks.el
+++ b/lisp/epa-ks.el
@@ -41,7 +41,7 @@
(defcustom epa-keyserver "pgp.mit.edu"
"Domain of keyserver.
-This is used by `epa-ks-lookup-key', for looking up public keys."
+This is used by `epa-search-keys', for looking up public keys."
:type '(choice :tag "Keyserver"
(repeat :tag "Random pool"
(string :tag "Keyserver address"))
@@ -66,14 +66,12 @@ This is used by `epa-ks-lookup-key', for looking up public keys."
"List of arguments to pass to `epa-search-keys'.
This is used when reverting a buffer to restart search.")
-(defvar epa-ks-search-mode-map
- (let ((map (make-sparse-keymap)))
- (suppress-keymap map)
- (define-key map (kbd "f") #'epa-ks-mark-key-to-fetch)
- (define-key map (kbd "i") #'epa-ks-inspect-key-to-fetch)
- (define-key map (kbd "u") #'epa-ks-unmark-key-to-fetch)
- (define-key map (kbd "x") #'epa-ks-do-key-to-fetch)
- map))
+(defvar-keymap epa-ks-search-mode-map
+ :suppress t
+ "f" #'epa-ks-mark-key-to-fetch
+ "i" #'epa-ks-inspect-key-to-fetch
+ "u" #'epa-ks-unmark-key-to-fetch
+ "x" #'epa-ks-do-key-to-fetch)
(define-derived-mode epa-ks-search-mode tabulated-list-mode "Keyserver"
"Major mode for listing public key search results."
@@ -182,7 +180,7 @@ If EXACT is non-nil, don't accept approximate matches."
"Prepare KEYS for `tabulated-list-mode', for buffer BUF.
KEYS is a list of `epa-ks-key' structures, as parsed by
-`epa-ks-parse-result'."
+`epa-ks--parse-buffer'."
(when (buffer-live-p buf)
(let (entries)
(dolist (key keys)
diff --git a/lisp/epa.el b/lisp/epa.el
index 63bc0941d62..cb87d808857 100644
--- a/lisp/epa.el
+++ b/lisp/epa.el
@@ -183,28 +183,26 @@ You should bind this variable with `let', but do not set it globally.")
(defvar epa-suppress-error-buffer nil)
(defvar epa-last-coding-system-specified nil)
-(defvar epa-key-list-mode-map
- (let ((keymap (make-sparse-keymap)))
- (define-key keymap "\C-m" 'epa-show-key)
- (define-key keymap [?\t] 'forward-button)
- (define-key keymap [backtab] 'backward-button)
- (define-key keymap "m" 'epa-mark-key)
- (define-key keymap "u" 'epa-unmark-key)
- (define-key keymap "d" 'epa-decrypt-file)
- (define-key keymap "v" 'epa-verify-file)
- (define-key keymap "s" 'epa-sign-file)
- (define-key keymap "e" 'epa-encrypt-file)
- (define-key keymap "r" 'epa-delete-keys)
- (define-key keymap "i" 'epa-import-keys)
- (define-key keymap "o" 'epa-export-keys)
- (define-key keymap "g" 'revert-buffer)
- (define-key keymap "n" 'next-line)
- (define-key keymap "p" 'previous-line)
- (define-key keymap " " 'scroll-up-command)
- (define-key keymap [?\S-\ ] 'scroll-down-command)
- (define-key keymap [delete] 'scroll-down-command)
- (define-key keymap "q" 'epa-exit-buffer)
- keymap))
+(defvar-keymap epa-key-list-mode-map
+ "RET" #'epa-show-key
+ "TAB" #'forward-button
+ "<backtab>" #'backward-button
+ "m" #'epa-mark-key
+ "u" #'epa-unmark-key
+ "d" #'epa-decrypt-file
+ "v" #'epa-verify-file
+ "s" #'epa-sign-file
+ "e" #'epa-encrypt-file
+ "r" #'epa-delete-keys
+ "i" #'epa-import-keys
+ "o" #'epa-export-keys
+ "g" #'revert-buffer
+ "n" #'next-line
+ "p" #'previous-line
+ "SPC" #'scroll-up-command
+ "S-SPC" #'scroll-down-command
+ "<delete>" #'scroll-down-command
+ "q" #'epa-exit-buffer)
(easy-menu-define epa-key-list-mode-menu epa-key-list-mode-map
"Menu for `epa-key-list-mode'."
@@ -230,10 +228,8 @@ You should bind this variable with `let', but do not set it globally.")
["Unmark Key" epa-unmark-key
:help "Unmark a key"]))
-(defvar epa-key-mode-map
- (let ((keymap (make-sparse-keymap)))
- (define-key keymap "q" 'epa-exit-buffer)
- keymap))
+(defvar-keymap epa-key-mode-map
+ "q" #'epa-exit-buffer)
(defvar epa-exit-buffer-function #'quit-window)
diff --git a/lisp/epg.el b/lisp/epg.el
index c3c26badbba..ceeb269b070 100644
--- a/lisp/epg.el
+++ b/lisp/epg.el
@@ -1519,12 +1519,8 @@ If you are unsure, use synchronous version of this function
(process-send-eof (epg-context-process context))))
;; Normal (or cleartext) signature.
(if (epg-data-file signature)
- (epg--start context (if (eq (epg-context-protocol context) 'CMS)
- (list "--verify" "--" (epg-data-file signature))
- (list "--" (epg-data-file signature))))
- (epg--start context (if (eq (epg-context-protocol context) 'CMS)
- '("--verify" "-")
- '("-")))
+ (epg--start context (list "--verify" "--" (epg-data-file signature)))
+ (epg--start context '("--verify" "-"))
(if (eq (process-status (epg-context-process context)) 'run)
(process-send-string (epg-context-process context)
(epg-data-string signature)))
diff --git a/lisp/erc/ChangeLog.1 b/lisp/erc/ChangeLog.1
index 0ea7ef09aa7..8fc97854303 100644
--- a/lisp/erc/ChangeLog.1
+++ b/lisp/erc/ChangeLog.1
@@ -3779,7 +3779,7 @@
doesn't appear).
* NEWS: Added the information from
- http://emacswiki.org/cgi-bin/wiki/ErcCvsFeatures and the newer
+ https://emacswiki.org/cgi-bin/wiki/ErcCvsFeatures and the newer
changes which weren't yet documented on that page.
2005-01-06 Hoan Ton-That <hoan@ton-that.org>
@@ -8298,7 +8298,7 @@
it doesn't move point to end-of-buffer in non-ERC buffers. Fixed
erc-kill-buffer-function so it doesn't run the erc-kill-server-hook hooks if the
server connection is closed. Fixed bug 658552, which is described in detail at
- http://sourceforge.net/tracker/index.php?func=detail&aid=658552&group_id=30118&atid=398125
+ https://sourceforge.net/tracker/index.php?func=detail&aid=658552&group_id=30118&atid=398125
2002-12-26 Alex Schroeder <alex@gnu.org>
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index bccf0e6f1f5..445595e2dad 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -248,7 +248,6 @@ specified by `erc-button-alist'."
(save-excursion
(with-syntax-table erc-button-syntax-table
(let ((buffer-read-only nil)
- (inhibit-point-motion-hooks t)
(inhibit-field-text-motion t)
(alist erc-button-alist)
regexp)
diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el
index 7c9174ff66a..6b9aa47d86d 100644
--- a/lisp/erc/erc-match.el
+++ b/lisp/erc/erc-match.el
@@ -240,6 +240,15 @@ server and other miscellaneous functions."
:version "24.3"
:type 'boolean)
+(defcustom erc-match-quote-when-adding 'ask
+ "Whether to `regexp-quote' when adding to a match list interactively.
+When the value is a boolean, the opposite behavior will be made
+available via universal argument."
+ :package-version '(ERC . "5.4.1") ; FIXME increment on next release
+ :type '(choice (const ask)
+ (const t)
+ (const nil)))
+
;; Internal variables:
;; This is exactly the same as erc-button-syntax-table. Should we
@@ -290,7 +299,7 @@ Note that this is the default face to use if
;; Functions:
-(defun erc-add-entry-to-list (list prompt &optional completions)
+(defun erc-add-entry-to-list (list prompt &optional completions alt)
"Add an entry interactively to a list.
LIST must be passed as a symbol
The query happens using PROMPT.
@@ -299,7 +308,16 @@ Completion is performed on the optional alist COMPLETIONS."
prompt
completions
(lambda (x)
- (not (erc-member-ignore-case (car x) (symbol-value list)))))))
+ (not (erc-member-ignore-case (car x) (symbol-value list))))))
+ quoted)
+ (setq quoted (regexp-quote entry))
+ (when (pcase erc-match-quote-when-adding
+ ('ask (unless (string= quoted entry)
+ (y-or-n-p
+ (format "Use regexp-quoted form (%s) instead? " quoted))))
+ ('t (not alt))
+ ('nil alt))
+ (setq entry quoted))
(if (erc-member-ignore-case entry (symbol-value list))
(error "\"%s\" is already on the list" entry)
(set list (cons entry (symbol-value list))))))
@@ -327,10 +345,11 @@ car is the string."
(symbol-value list))))))
;;;###autoload
-(defun erc-add-pal ()
+(defun erc-add-pal (&optional arg)
"Add pal interactively to `erc-pals'."
- (interactive)
- (erc-add-entry-to-list 'erc-pals "Add pal: " (erc-get-server-nickname-alist)))
+ (interactive "P")
+ (erc-add-entry-to-list 'erc-pals "Add pal: "
+ (erc-get-server-nickname-alist) arg))
;;;###autoload
(defun erc-delete-pal ()
@@ -339,11 +358,11 @@ car is the string."
(erc-remove-entry-from-list 'erc-pals "Delete pal: "))
;;;###autoload
-(defun erc-add-fool ()
+(defun erc-add-fool (&optional arg)
"Add fool interactively to `erc-fools'."
- (interactive)
+ (interactive "P")
(erc-add-entry-to-list 'erc-fools "Add fool: "
- (erc-get-server-nickname-alist)))
+ (erc-get-server-nickname-alist) arg))
;;;###autoload
(defun erc-delete-fool ()
@@ -352,10 +371,10 @@ car is the string."
(erc-remove-entry-from-list 'erc-fools "Delete fool: "))
;;;###autoload
-(defun erc-add-keyword ()
+(defun erc-add-keyword (&optional arg)
"Add keyword interactively to `erc-keywords'."
- (interactive)
- (erc-add-entry-to-list 'erc-keywords "Add keyword: "))
+ (interactive "P")
+ (erc-add-entry-to-list 'erc-keywords "Add keyword: " nil arg))
;;;###autoload
(defun erc-delete-keyword ()
@@ -364,10 +383,10 @@ car is the string."
(erc-remove-entry-from-list 'erc-keywords "Delete keyword: "))
;;;###autoload
-(defun erc-add-dangerous-host ()
+(defun erc-add-dangerous-host (&optional arg)
"Add dangerous-host interactively to `erc-dangerous-hosts'."
- (interactive)
- (erc-add-entry-to-list 'erc-dangerous-hosts "Add dangerous-host: "))
+ (interactive "P")
+ (erc-add-entry-to-list 'erc-dangerous-hosts "Add dangerous-host: " nil arg))
;;;###autoload
(defun erc-delete-dangerous-host ()
@@ -388,19 +407,19 @@ NICKUSERHOST will be ignored."
(defun erc-match-pal-p (nickuserhost _msg)
"Check whether NICKUSERHOST is in `erc-pals'.
MSG will be ignored."
- (and nickuserhost
+ (and nickuserhost erc-pals
(erc-list-match erc-pals nickuserhost)))
(defun erc-match-fool-p (nickuserhost msg)
"Check whether NICKUSERHOST is in `erc-fools' or MSG is directed at a fool."
- (and msg nickuserhost
+ (and msg nickuserhost erc-fools
(or (erc-list-match erc-fools nickuserhost)
(erc-match-directed-at-fool-p msg))))
(defun erc-match-keyword-p (_nickuserhost msg)
"Check whether any keyword of `erc-keywords' matches for MSG.
NICKUSERHOST will be ignored."
- (and msg
+ (and msg erc-keywords
(erc-list-match
(mapcar (lambda (x)
(if (listp x)
@@ -412,7 +431,7 @@ NICKUSERHOST will be ignored."
(defun erc-match-dangerous-host-p (nickuserhost _msg)
"Check whether NICKUSERHOST is in `erc-dangerous-hosts'.
MSG will be ignored."
- (and nickuserhost
+ (and nickuserhost erc-dangerous-hosts
(erc-list-match erc-dangerous-hosts nickuserhost)))
(defun erc-match-directed-at-fool-p (msg)
diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el
index c54b12fcb0b..2c8f8fb72bb 100644
--- a/lisp/erc/erc-networks.el
+++ b/lisp/erc/erc-networks.el
@@ -996,8 +996,8 @@ Rename the current buffer if its NID has grown."
"Return a list of target BUFFERS, newest to oldest."
(sort buffers
(lambda (a b)
- (> (with-current-buffer a (erc-networks--id-ts erc-networks--id))
- (with-current-buffer b (erc-networks--id-ts erc-networks--id))))))
+ (> (erc-networks--id-ts (buffer-local-value 'erc-networks--id a))
+ (erc-networks--id-ts (buffer-local-value 'erc-networks--id b))))))
;;;; Buffer association
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 151d75e7ce1..db39e341b2f 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -1651,7 +1651,7 @@ Defaults to the server buffer."
"IRC port to use for encrypted connections if it cannot be \
detected otherwise.")
-(defcustom erc-join-buffer 'buffer
+(defcustom erc-join-buffer 'bury
"Determines how to display a newly created IRC buffer.
The available choices are:
@@ -1662,6 +1662,7 @@ The available choices are:
`bury' - bury it in a new buffer,
`buffer' - in place of the current buffer,
any other value - in place of the current buffer."
+ :package-version '(ERC . "5.4.1") ; FIXME increment upon publishing to ELPA
:group 'erc-buffers
:type '(choice (const :tag "Split window and select" window)
(const :tag "Split window, don't select" window-noselect)
@@ -2148,7 +2149,7 @@ removed from the list will be disabled."
(display-buffer buffer)
(switch-to-buffer-other-window buffer)))
('window-noselect
- (display-buffer buffer))
+ (display-buffer buffer '(nil (inhibit-same-window . t))))
('bury
nil)
('frame
@@ -2571,7 +2572,8 @@ workaround."
(with-current-buffer (get-buffer-create "*erc-protocol*")
(save-excursion
(goto-char (point-max))
- (let ((inhibit-read-only t))
+ (let ((buffer-undo-list t)
+ (inhibit-read-only t))
(insert (if outbound
(concat ts esid " >> " string)
;; Cope with multi-line messages
@@ -2747,8 +2749,7 @@ current session. `active' means the current active buffer
buffer is used. `erc-display-line-1' is used to display STRING.
If STRING is nil, the function does nothing."
- (let ((inhibit-point-motion-hooks t)
- new-bufs)
+ (let (new-bufs)
(dolist (buf (cond
((bufferp buffer) (list buffer))
((listp buffer) buffer)
@@ -6283,9 +6284,7 @@ The addressed target is the string before the first colon in MSG."
(defun erc-list-match (lst str)
"Return non-nil if any regexp in LST matches STR."
- (memq nil (mapcar (lambda (regexp)
- (not (string-match regexp str)))
- lst)))
+ (and lst (string-match (string-join lst "\\|") str)))
;; other "toggles"
@@ -6962,6 +6961,8 @@ shortened server name instead."
(defvar tabbar--local-hlf)
+;; FIXME when 29.1 is cut and `format-spec' is added to ELPA Compat,
+;; remove the function invocations from the spec form below.
(defun erc-update-mode-line-buffer (buffer)
"Update the mode line in a single ERC buffer BUFFER."
(with-current-buffer buffer
@@ -7326,7 +7327,7 @@ See also `format-spec'."
(error "No format spec for message %s" msg))
(when (functionp entry)
(setq entry (apply entry args)))
- (format-spec entry (apply #'format-spec-make args))))
+ (format-spec entry (apply #'format-spec-make args) 'ignore)))
;;; Various hook functions
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el
index 822cc941491..ac82e3f225c 100644
--- a/lisp/eshell/em-cmpl.el
+++ b/lisp/eshell/em-cmpl.el
@@ -378,6 +378,31 @@ to writing a completion function."
args)
posns)))
+(defun eshell--pcomplete-executables ()
+ "Complete amongst a list of directories and executables.
+
+Wrapper for `pcomplete-executables' or `pcomplete-dirs-or-entries',
+depending on the value of `eshell-force-execution'.
+
+Adds path prefix to candidates independent of `action' value."
+ ;; `pcomplete-entries' returns filenames without path on `action' to
+ ;; use current string directory as done in `completion-file-name-table'
+ ;; when `action' is nil to construct executable candidates.
+ (let ((table (if eshell-force-execution
+ (pcomplete-dirs-or-entries nil #'file-readable-p)
+ (pcomplete-executables))))
+ (lambda (string pred action)
+ (let ((cands (funcall table string pred action)))
+ (if (eq action t)
+ (let ((specdir (file-name-directory string)))
+ (mapcar
+ (lambda (cand)
+ (if (stringp cand)
+ (file-name-concat specdir cand)
+ cand))
+ cands))
+ cands)))))
+
(defun eshell--complete-commands-list ()
"Generate list of applicable, visible commands."
;; Building the commands list can take quite a while, especially over Tramp
@@ -392,9 +417,7 @@ to writing a completion function."
(completion-table-dynamic
(lambda (filename)
(if (file-name-directory filename)
- (if eshell-force-execution
- (pcomplete-dirs-or-entries nil #'file-readable-p)
- (pcomplete-executables))
+ (eshell--pcomplete-executables)
(let* ((paths (eshell-get-path))
(cwd (file-name-as-directory
(expand-file-name default-directory)))
diff --git a/lisp/eshell/em-glob.el b/lisp/eshell/em-glob.el
index 58b7a83c091..9722aeae18e 100644
--- a/lisp/eshell/em-glob.el
+++ b/lisp/eshell/em-glob.el
@@ -202,7 +202,7 @@ The basic syntax is:
[a-b] [a-b] matches a character or range
[^a] [^a] excludes a character or range
-If any characters in PATTERN have the text property `eshell-escaped'
+If any characters in PATTERN have the text property `escaped'
set to true, then these characters will match themselves in the
resulting regular expression."
(let ((matched-in-pattern 0) ; How much of PATTERN handled
diff --git a/lisp/eshell/em-script.el b/lisp/eshell/em-script.el
index e0bcd8b099f..06ddda1424f 100644
--- a/lisp/eshell/em-script.el
+++ b/lisp/eshell/em-script.el
@@ -90,8 +90,7 @@ This includes when running `eshell-command'."
"Execute a series of Eshell commands in FILE, passing ARGS.
Comments begin with `#'."
(let ((orig (point))
- (here (point-max))
- (inhibit-point-motion-hooks t))
+ (here (point-max)))
(goto-char (point-max))
(with-silent-modifications
;; FIXME: Why not use a temporary buffer and avoid this
diff --git a/lisp/eshell/em-smart.el b/lisp/eshell/em-smart.el
index 6768cee4c34..c52ce318997 100644
--- a/lisp/eshell/em-smart.el
+++ b/lisp/eshell/em-smart.el
@@ -197,8 +197,7 @@ The options are `begin', `after' or `end'."
(defun eshell-smart-scroll-window (wind _start)
"Scroll the given Eshell window WIND accordingly."
(unless eshell-currently-handling-window
- (let ((inhibit-point-motion-hooks t)
- (eshell-currently-handling-window t))
+ (let ((eshell-currently-handling-window t))
(with-selected-window wind
(eshell-smart-redisplay)))))
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el
index 40b83010f94..4b5e4dd53ed 100644
--- a/lisp/eshell/em-unix.el
+++ b/lisp/eshell/em-unix.el
@@ -372,12 +372,10 @@ Remove the DIRECTORY(ies), if they are empty.")
(setq attr (eshell-file-attributes (car files)))
(file-attribute-inode-number attr-target)
(file-attribute-inode-number attr)
- (equal (file-attribute-inode-number attr-target)
- (file-attribute-inode-number attr))
(file-attribute-device-number attr-target)
(file-attribute-device-number attr)
- (equal (file-attribute-device-number attr-target)
- (file-attribute-device-number attr)))
+ (equal (file-attribute-file-identifier attr-target)
+ (file-attribute-file-identifier attr)))
(eshell-error (format-message "%s: `%s' and `%s' are the same file\n"
command (car files) target)))
(t
diff --git a/lisp/eshell/esh-arg.el b/lisp/eshell/esh-arg.el
index 576d32b8c5d..f87cc2f20aa 100644
--- a/lisp/eshell/esh-arg.el
+++ b/lisp/eshell/esh-arg.el
@@ -285,8 +285,7 @@ Point is left at the end of the arguments."
(save-restriction
(goto-char beg)
(narrow-to-region beg end)
- (let ((inhibit-point-motion-hooks t)
- (args (list t))
+ (let ((args (list t))
delim)
(with-silent-modifications
(remove-text-properties (point-min) (point-max)
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 413336e3eb5..3f3a1616eee 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -372,8 +372,7 @@ The value returned is the last form in BODY."
;; Since parsing relies partly on buffer-local state
;; (e.g. that of `eshell-parse-argument-hook'), we need to
;; perform the parsing in the Eshell buffer.
- (let ((begin (point)) end
- (inhibit-point-motion-hooks t))
+ (let ((begin (point)) end)
(with-silent-modifications
(insert reg)
(setq end (point))
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index 69069183a3f..92523fd99ea 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -331,7 +331,6 @@ and the hook `eshell-exit-hook'."
(setq-local require-final-newline nil)
(setq-local max-lisp-eval-depth (max 3000 max-lisp-eval-depth))
- (setq-local max-specpdl-size (max 6000 max-lisp-eval-depth))
(setq-local eshell-last-input-start (point-marker))
(setq-local eshell-last-input-end (point-marker))
@@ -599,7 +598,6 @@ newline."
;; Note that the input string does not include its terminal newline.
(let ((proc-running-p (and (eshell-head-process)
(not queue-p)))
- (inhibit-point-motion-hooks t)
(inhibit-modification-hooks t))
(unless (and proc-running-p
(not (eq (process-status
@@ -688,7 +686,6 @@ newline."
This is done after all necessary filtering has been done."
(let ((oprocbuf (if process (process-buffer process)
(current-buffer)))
- (inhibit-point-motion-hooks t)
(inhibit-modification-hooks t))
(when (and string oprocbuf (buffer-name oprocbuf))
(with-current-buffer oprocbuf
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index 7e005a0fc1c..bb928fc5fb0 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -277,7 +277,23 @@ Used only on systems which do not support async subprocesses.")
eshell-delete-exited-processes
delete-exited-processes))
(process-environment (eshell-environment-variables))
+ (coding-system-for-read coding-system-for-read)
+ (coding-system-for-write coding-system-for-write)
proc stderr-proc decoding encoding changed)
+ ;; MS-Windows needs special setting of encoding/decoding, because
+ ;; (a) non-ASCII text in command-line arguments needs to be
+ ;; encoded in the system's codepage; and (b) because many Windows
+ ;; programs will always interpret any non-ASCII input as encoded
+ ;; in the system codepage.
+ (when (eq system-type 'windows-nt)
+ (or coding-system-for-read ; Honor manual decoding settings
+ (setq coding-system-for-read
+ (coding-system-change-eol-conversion locale-coding-system
+ 'dos)))
+ (or coding-system-for-write ; Honor manual encoding settings
+ (setq coding-system-for-write
+ (coding-system-change-eol-conversion locale-coding-system
+ 'unix))))
(cond
((fboundp 'make-process)
(unless (equal (car (aref eshell-current-handles eshell-output-handle))
@@ -325,7 +341,7 @@ Used only on systems which do not support async subprocesses.")
(setq decoding (coding-system-change-eol-conversion decoding 'dos)
changed t))
;; Even if `make-process' left the coding system for encoding
- ;; data sent from the process undecided, we had better use the
+ ;; data sent to the process undecided, we had better use the
;; same one as what we use for decoding. But, we should
;; suppress EOL conversion.
(if (and decoding (not encoding))
diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el
index a9df172e88e..36e59cd5a41 100644
--- a/lisp/eshell/esh-var.el
+++ b/lisp/eshell/esh-var.el
@@ -646,23 +646,24 @@ For example, to retrieve the second element of a user's record in
"Reference VALUE using the given INDEX."
(when (and (stringp index) (get-text-property 0 'number index))
(setq index (string-to-number index)))
- (if (stringp index)
- (cdr (assoc index value))
- (cond
- ((ring-p value)
- (if (> index (ring-length value))
- (error "Index exceeds length of ring")
- (ring-ref value index)))
- ((listp value)
- (if (> index (length value))
- (error "Index exceeds length of list")
- (nth index value)))
- ((vectorp value)
- (if (> index (length value))
- (error "Index exceeds length of vector")
- (aref value index)))
- (t
- (error "Invalid data type for indexing")))))
+ (if (integerp index)
+ (cond
+ ((ring-p value)
+ (if (> index (ring-length value))
+ (error "Index exceeds length of ring")
+ (ring-ref value index)))
+ ((listp value)
+ (if (> index (length value))
+ (error "Index exceeds length of list")
+ (nth index value)))
+ ((vectorp value)
+ (if (> index (length value))
+ (error "Index exceeds length of vector")
+ (aref value index)))
+ (t
+ (error "Invalid data type for indexing")))
+ ;; INDEX is some non-integer value, so treat VALUE as an alist.
+ (cdr (assoc index value))))
;;;_* Variable name completion
diff --git a/lisp/faces.el b/lisp/faces.el
index e171b32e317..09e81104491 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2060,7 +2060,7 @@ IF MULTIPLE is non-nil, return a list of faces.
Return nil if there is no face at point.
-This function is not meant for handling faces programatically; to
+This function is not meant for handling faces programmatically; to
do that, use `get-text-property' and `get-char-property'."
(let (faces)
(when text
@@ -2548,7 +2548,6 @@ default."
:version "21.1"
:group 'basic-faces)
-;; Definition stolen from linum.el.
(defface line-number
'((t :inherit (shadow default)))
"Face for displaying line numbers.
diff --git a/lisp/ffap.el b/lisp/ffap.el
index 7ea05dccbdd..482ac3764a2 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -1504,7 +1504,11 @@ which may actually result in an URL rather than a filename."
(progn
(push elem file-name-handler-alist)
(if (ffap-url-p guess)
- (read-file-name prompt guess guess)
+ ;; We're using the default file name prompter here -- it
+ ;; allows you to switch back to reading a file name,
+ ;; while other prompters, like ido, really expect a
+ ;; file, and don't allow you to edit it if it's an URL.
+ (funcall #'read-file-name-default prompt guess guess)
(unless guess
(setq guess default-directory))
(unless (ffap-file-remote-p guess)
diff --git a/lisp/filenotify.el b/lisp/filenotify.el
index 94e07289e32..6b13ed0b725 100644
--- a/lisp/filenotify.el
+++ b/lisp/filenotify.el
@@ -339,6 +339,7 @@ DESC is the back-end descriptor. ACTIONS is a list of:
"Add a watch for FILE in DIR with FLAGS, using inotify."
(inotify-add-watch dir
(append
+ '(dont-follow)
(and (memq 'change flags)
'(create delete delete-self modify move-self move))
(and (memq 'attribute-change flags)
diff --git a/lisp/files-x.el b/lisp/files-x.el
index da1e44e2504..0131d495f27 100644
--- a/lisp/files-x.el
+++ b/lisp/files-x.el
@@ -489,7 +489,9 @@ from the MODE alist ignoring the input argument VALUE."
dir-locals-directory-cache))
;; Insert modified alist of directory-local variables.
- (insert ";;; Directory Local Variables\n")
+ ;; When changing this, also update the ".dir-locals.el" file for
+ ;; Emacs itself, as well as the template in autoinsert.el.
+ (insert ";;; Directory Local Variables -*- no-byte-compile: t -*-\n")
(insert ";;; For more information see (info \"(emacs) Directory Variables\")\n\n")
(princ (dir-locals-to-string
(sort variables
diff --git a/lisp/files.el b/lisp/files.el
index 540bc2a6a85..3fa0f2f3b81 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -208,9 +208,10 @@ if the file has changed on disk and you have not edited the buffer."
:group 'find-file)
(defvar-local buffer-file-number nil
- "The device number and file number of the file visited in the current buffer.
-The value is a list of the form (FILENUM DEVNUM).
-This pair of numbers uniquely identifies the file.
+ "The inode number and the device of the file visited in the current buffer.
+The value is a list of the form (INODENUM DEVICE), where DEVICE can be
+either a single number or a cons cell of two numbers.
+This tuple of numbers uniquely identifies the file.
If the buffer is visiting a new file, the value is nil.")
(put 'buffer-file-number 'permanent-local t)
@@ -2163,7 +2164,7 @@ If there is no such live buffer, return nil."
(setq list (cdr list)))
found)
(let* ((attributes (file-attributes truename))
- (number (nthcdr 10 attributes))
+ (number (file-attribute-file-identifier attributes))
(list (buffer-list)) found)
(and buffer-file-numbers-unique
(car-safe number) ;Make sure the inode is not just nil.
@@ -2366,7 +2367,7 @@ the various files."
(let* ((buf (get-file-buffer filename))
(truename (abbreviate-file-name (file-truename filename)))
(attributes (file-attributes truename))
- (number (nthcdr 10 attributes))
+ (number (file-attribute-file-identifier attributes))
;; Find any buffer for a file that has same truename.
(other (and (not buf)
(find-buffer-visiting
@@ -2379,16 +2380,15 @@ the various files."
'buffer-file-name buffer)))
(and file (file-exists-p file))))))))
;; Let user know if there is a buffer with the same truename.
- (if other
- (progn
- (or nowarn
- find-file-suppress-same-file-warnings
- (string-equal filename (buffer-file-name other))
- (files--message "%s and %s are the same file"
- filename (buffer-file-name other)))
- ;; Optionally also find that buffer.
- (if (or find-file-existing-other-name find-file-visit-truename)
- (setq buf other))))
+ (when other
+ (or nowarn
+ find-file-suppress-same-file-warnings
+ (string-equal filename (buffer-file-name other))
+ (files--message "%s and %s are the same file"
+ filename (buffer-file-name other)))
+ ;; Optionally also find that buffer.
+ (if (or find-file-existing-other-name find-file-visit-truename)
+ (setq buf other)))
;; Check to see if the file looks uncommonly large.
(when (not (or buf nowarn))
(when (eq (abort-if-file-too-large
@@ -2711,7 +2711,8 @@ unless NOMODES is non-nil."
(file-newer-than-file-p (or buffer-auto-save-file-name
(make-auto-save-file-name))
buffer-file-name))
- (format "%s has auto save data; consider M-x recover-this-file"
+ (format (substitute-command-keys
+ "%s has auto save data; consider \\`M-x recover-this-file'")
(file-name-nondirectory buffer-file-name))
(setq not-serious t)
(if error "(New file)" nil)))
@@ -3016,6 +3017,7 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\|SQUASHFS\\)\\'" .
("[cC]hange[lL]og[-.][-0-9a-z]+\\'" . change-log-mode)
;; either user's dot-files or under /etc or some such
("/\\.?\\(?:gitconfig\\|gnokiirc\\|hgrc\\|kde.*rc\\|mime\\.types\\|wgetrc\\)\\'" . conf-mode)
+ ("/\\.mailmap\\'" . conf-unix-mode)
;; alas not all ~/.*rc files are like this
("/\\.\\(?:asound\\|enigma\\|fetchmail\\|gltron\\|gtk\\|hxplayer\\|mairix\\|mbsync\\|msmtp\\|net\\|neverball\\|nvidia-settings-\\|offlineimap\\|qt/.+\\|realplayer\\|reportbug\\|rtorrent\\.\\|screen\\|scummvm\\|sversion\\|sylpheed/.+\\|xmp\\)rc\\'" . conf-mode)
("/\\.\\(?:gdbtkinit\\|grip\\|mpdconf\\|notmuch-config\\|orbital/.+txt\\|rhosts\\|tuxracer/options\\)\\'" . conf-mode)
@@ -3331,6 +3333,7 @@ checks if it uses an interpreter listed in `interpreter-mode-alist',
matches the buffer beginning against `magic-mode-alist',
compares the file name against the entries in `auto-mode-alist',
then matches the buffer beginning against `magic-fallback-mode-alist'.
+It also obeys `major-mode-remap-alist'.
If `enable-local-variables' is nil, or if the file name matches
`inhibit-local-variables-regexps', this function does not check
@@ -3468,6 +3471,17 @@ we don't actually set it to the same mode the buffer already has."
(unless done
(set-buffer-major-mode (current-buffer)))))
+(defvar-local set-auto-mode--last nil
+ "Remember the mode we have set via `set-auto-mode-0'.")
+
+(defcustom major-mode-remap-alist nil
+ "Alist mapping file-specified mode to actual mode.
+Every entry is of the form (MODE . FUNCTION) which means that in order
+to activate the major mode MODE (specified via something like
+`auto-mode-alist', file-local variables, ...) we should actually call
+FUNCTION instead."
+ :type '(alist (symbol) (function)))
+
;; When `keep-mode-if-same' is set, we are working on behalf of
;; set-visited-file-name. In that case, if the major mode specified is the
;; same one we already have, don't actually reset it. We don't want to lose
@@ -3478,10 +3492,15 @@ If optional arg KEEP-MODE-IF-SAME is non-nil, MODE is chased of
any aliases and compared to current major mode. If they are the
same, do nothing and return nil."
(unless (and keep-mode-if-same
- (eq (indirect-function mode)
- (indirect-function major-mode)))
+ (or (eq (indirect-function mode)
+ (indirect-function major-mode))
+ (and set-auto-mode--last
+ (eq mode (car set-auto-mode--last))
+ (eq major-mode (cdr set-auto-mode--last)))))
(when mode
- (funcall mode)
+ (funcall (alist-get mode major-mode-remap-alist mode))
+ (unless (eq mode major-mode)
+ (setq set-auto-mode--last (cons mode major-mode)))
mode)))
(defvar file-auto-mode-skip "^\\(#!\\|'\\\\\"\\)"
@@ -3511,7 +3530,8 @@ have no effect."
;; interpreter invocation. The same holds
;; for '\" in man pages (preprocessor
;; magic for the `man' program).
- (and (looking-at file-auto-mode-skip) 2)) t)
+ (and (looking-at file-auto-mode-skip) 2))
+ t)
(progn
(skip-chars-forward " \t")
(setq beg (point))
@@ -3593,7 +3613,6 @@ asking you for confirmation."
inhibit-quit
load-path
max-lisp-eval-depth
- max-specpdl-size
minor-mode-map-alist
minor-mode-overriding-map-alist
mode-line-format
@@ -4726,7 +4745,7 @@ the old visited file has been renamed to the new name FILENAME."
(setq buffer-file-name truename))))
(setq buffer-file-number
(if filename
- (nthcdr 10 (file-attributes buffer-file-name))
+ (file-attribute-file-identifier (file-attributes buffer-file-name))
nil))
;; write-file-functions is normally used for things like ftp-find-file
;; that visit things that are not local files as if they were files.
@@ -4866,6 +4885,14 @@ Interactively, this prompts for NEW-LOCATION."
(expand-file-name
(file-name-nondirectory (buffer-name))
default-directory)))))
+ ;; If the user has given a directory name, the file should be moved
+ ;; there (under the same file name).
+ (when (file-directory-p new-location)
+ (unless buffer-file-name
+ (user-error "Can't rename buffer to a directory file name"))
+ (setq new-location (expand-file-name
+ (file-name-nondirectory buffer-file-name)
+ new-location)))
(when (and buffer-file-name
(file-exists-p buffer-file-name))
(rename-file buffer-file-name new-location))
@@ -5174,7 +5201,7 @@ On most systems, this will be true:
(setq filename nil))))
components))
-(defun file-parent-directory (filename)
+(defun file-name-parent-directory (filename)
"Return the directory name of the parent directory of FILENAME.
If FILENAME is at the root of the filesystem, return nil.
If FILENAME is relative, it is interpreted to be relative
@@ -5707,7 +5734,8 @@ Before and after saving the buffer, this function runs
(setq save-buffer-coding-system last-coding-system-used)
(setq buffer-file-coding-system last-coding-system-used))
(setq buffer-file-number
- (nthcdr 10 (file-attributes buffer-file-name)))
+ (file-attribute-file-identifier
+ (file-attributes buffer-file-name)))
(if setmodes
(condition-case ()
(progn
@@ -6128,16 +6156,17 @@ recent files are first."
(let* ((filename (file-name-sans-versions
(make-backup-file-name (expand-file-name filename))))
(dir (file-name-directory filename)))
- (sort
- (seq-filter
- (lambda (candidate)
- (and (backup-file-name-p candidate)
- (string= (file-name-sans-versions candidate) filename)))
- (mapcar
- (lambda (file)
- (concat dir file))
- (file-name-all-completions (file-name-nondirectory filename) dir)))
- #'file-newer-than-file-p)))
+ (when (file-directory-p dir)
+ (sort
+ (seq-filter
+ (lambda (candidate)
+ (and (backup-file-name-p candidate)
+ (string= (file-name-sans-versions candidate) filename)))
+ (mapcar
+ (lambda (file)
+ (concat dir file))
+ (file-name-all-completions (file-name-nondirectory filename) dir)))
+ #'file-newer-than-file-p))))
(defun rename-uniquely ()
"Rename current buffer to a similar name not already taken.
@@ -6317,9 +6346,10 @@ If FILE1 or FILE2 does not exist, the return value is unspecified."
(equal f1-attr f2-attr))))))
(defun file-in-directory-p (file dir)
- "Return non-nil if FILE is in DIR or a subdirectory of DIR.
-A directory is considered to be \"in\" itself.
-Return nil if DIR is not an existing directory."
+ "Return non-nil if DIR is a parent directory of FILE.
+Value is non-nil if FILE is inside DIR or inside a subdirectory of DIR.
+A directory is considered to be a \"parent\" of itself.
+DIR must be an existing directory, otherwise the function returns nil."
(let ((handler (or (find-file-name-handler file 'file-in-directory-p)
(find-file-name-handler dir 'file-in-directory-p))))
(if handler
@@ -8271,10 +8301,10 @@ CHAR is in [ugoa] and represents the category of users (Owner, Group,
Others, or All) for whom to produce the mask.
The bit-mask that is returned extracts from mode bits the access rights
for the specified category of users."
- (cond ((= char ?u) #o4700)
- ((= char ?g) #o2070)
- ((= char ?o) #o1007)
- ((= char ?a) #o7777)
+ (cond ((eq char ?u) #o4700)
+ ((eq char ?g) #o2070)
+ ((eq char ?o) #o1007)
+ ((eq char ?a) #o7777)
(t (error "%c: Bad `who' character" char))))
(defun file-modes-char-to-right (char &optional from)
@@ -8282,22 +8312,22 @@ for the specified category of users."
CHAR is in [rwxXstugo] and represents symbolic access permissions.
If CHAR is in [Xugo], the value is taken from FROM (or 0 if omitted)."
(or from (setq from 0))
- (cond ((= char ?r) #o0444)
- ((= char ?w) #o0222)
- ((= char ?x) #o0111)
- ((= char ?s) #o6000)
- ((= char ?t) #o1000)
+ (cond ((eq char ?r) #o0444)
+ ((eq char ?w) #o0222)
+ ((eq char ?x) #o0111)
+ ((eq char ?s) #o6000)
+ ((eq char ?t) #o1000)
;; Rights relative to the previous file modes.
- ((= char ?X) (if (= (logand from #o111) 0) 0 #o0111))
- ((= char ?u) (let ((uright (logand #o4700 from)))
- ;; FIXME: These divisions/shifts seem to be right
- ;; for the `7' part of the #o4700 mask, but not
- ;; for the `4' part. Same below for `g' and `o'.
- (+ uright (/ uright #o10) (/ uright #o100))))
- ((= char ?g) (let ((gright (logand #o2070 from)))
- (+ gright (/ gright #o10) (* gright #o10))))
- ((= char ?o) (let ((oright (logand #o1007 from)))
- (+ oright (* oright #o10) (* oright #o100))))
+ ((eq char ?X) (if (= (logand from #o111) 0) 0 #o0111))
+ ((eq char ?u) (let ((uright (logand #o4700 from)))
+ ;; FIXME: These divisions/shifts seem to be right
+ ;; for the `7' part of the #o4700 mask, but not
+ ;; for the `4' part. Same below for `g' and `o'.
+ (+ uright (/ uright #o10) (/ uright #o100))))
+ ((eq char ?g) (let ((gright (logand #o2070 from)))
+ (+ gright (/ gright #o10) (* gright #o10))))
+ ((eq char ?o) (let ((oright (logand #o1007 from)))
+ (+ oright (* oright #o10) (* oright #o100))))
(t (error "%c: Bad right character" char))))
(defun file-modes-rights-to-number (rights who-mask &optional from)
@@ -8630,19 +8660,26 @@ It is a nonnegative integer."
(defsubst file-attribute-device-number (attributes)
"The file system device number in ATTRIBUTES returned by `file-attributes'.
-It is an integer."
+It is an integer or a cons cell of integers."
(nth 11 attributes))
+(defsubst file-attribute-file-identifier (attributes)
+ "The inode and device numbers in ATTRIBUTES returned by `file-attributes'.
+The value is a list of the form (INODENUM DEVICE), where DEVICE could be
+either a single number or a cons cell of two numbers.
+This tuple of numbers uniquely identifies the file."
+ (nthcdr 10 attributes))
+
(defun file-attribute-collect (attributes &rest attr-names)
"Return a sublist of ATTRIBUTES returned by `file-attributes'.
ATTR-NAMES are symbols with the selected attribute names.
Valid attribute names are: type, link-number, user-id, group-id,
access-time, modification-time, status-change-time, size, modes,
-inode-number and device-number."
+inode-number, device-number and file-number."
(let ((all '(type link-number user-id group-id access-time
modification-time status-change-time
- size modes inode-number device-number))
+ size modes inode-number device-number file-number))
result)
(while attr-names
(let ((attr (pop attr-names)))
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index b6f4150964d..d132de3a322 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -633,16 +633,6 @@ Major/minor modes can set this variable if they know which option applies.")
;; Font Lock mode.
-(eval-when-compile
- ;;
- ;; We use this to preserve or protect things when modifying text properties.
- (defmacro save-buffer-state (&rest body)
- "Bind variables according to VARLIST and eval BODY restoring buffer state."
- (declare (indent 0) (debug t))
- `(let ((inhibit-point-motion-hooks t))
- (with-silent-modifications
- ,@body))))
-
(defvar-local font-lock-set-defaults nil) ; Whether we have set up defaults.
(defun font-lock-specified-p (mode)
@@ -1002,7 +992,7 @@ This works by calling `font-lock-fontify-region-function'."
(defun font-lock-unfontify-region (beg end)
"Unfontify the text between BEG and END.
This works by calling `font-lock-unfontify-region-function'."
- (save-buffer-state
+ (with-silent-modifications
(funcall font-lock-unfontify-region-function beg end)))
(defvar font-lock-flush-function #'font-lock-after-change-function
@@ -1152,7 +1142,7 @@ Put first the functions more likely to cause a change and cheaper to compute.")
"Fontify the text between BEG and END.
If LOUDLY is non-nil, print status messages while fontifying.
This function is the default `font-lock-fontify-region-function'."
- (save-buffer-state
+ (with-silent-modifications
;; Use the fontification syntax table, if any.
(with-syntax-table (or font-lock-syntax-table (syntax-table))
;; Extend the region to fontify so that it starts and ends at
@@ -1211,8 +1201,7 @@ This function is the default `font-lock-unfontify-region-function'."
;; Called when any modification is made to buffer text.
(defun font-lock-after-change-function (beg end &optional old-len)
(save-excursion
- (let ((inhibit-point-motion-hooks t)
- (inhibit-quit t)
+ (let ((inhibit-quit t)
(region (if font-lock-extend-after-change-region-function
(funcall font-lock-extend-after-change-region-function
beg end old-len))))
@@ -1307,8 +1296,7 @@ no ARG is given and `font-lock-mark-block-function' is nil.
If `font-lock-mark-block-function' non-nil and no ARG is given, it is used to
delimit the region to fontify."
(interactive "P")
- (let ((inhibit-point-motion-hooks t)
- deactivate-mark)
+ (let (deactivate-mark)
;; Make sure we have the right `font-lock-keywords' etc.
(if (not font-lock-mode) (font-lock-set-defaults))
(save-mark-and-excursion
diff --git a/lisp/format-spec.el b/lisp/format-spec.el
index 45c19aebc8b..60ff9f90864 100644
--- a/lisp/format-spec.el
+++ b/lisp/format-spec.el
@@ -59,6 +59,18 @@ value associated with ?b in SPECIFICATION, either padding it with
leading zeros or truncating leading characters until it's ten
characters wide\".
+the substitution for a specification character can also be a
+function, taking no arguments and returning a string to be used
+for the replacement. It will only be called if FORMAT uses that
+character. For example:
+
+ (format-spec \"%n\"
+ \\=`((?n . ,(lambda ()
+ (read-number \"Number: \")))))
+
+Note that it is best to make sure the function is not quoted,
+like above, so that it is compiled by the byte-compiler.
+
Any text properties of FORMAT are copied to the result, with any
text properties of a %-spec itself copied to its substitution.
@@ -94,14 +106,15 @@ is returned, where each format spec is its own element."
(width (match-string 2))
(trunc (match-string 3))
(char (string-to-char (match-string 4)))
- (text (assq char specification)))
+ (text (let ((res (cdr (assq char specification))))
+ (if (functionp res) (funcall res) res))))
(when (and split
(not (= (1- beg) split-start)))
(push (buffer-substring split-start (1- beg)) split-result))
(cond (text
;; Handle flags.
(setq text (format-spec--do-flags
- (format "%s" (cdr text))
+ (format "%s" text)
(format-spec--parse-flags flags)
(and width (string-to-number width))
(and trunc (car (read-from-string trunc 1)))))
diff --git a/lisp/format.el b/lisp/format.el
index 2c368b8f9c7..5cd2d4bfb49 100644
--- a/lisp/format.el
+++ b/lisp/format.el
@@ -440,10 +440,9 @@ a list (ABSOLUTE-FILE-NAME SIZE)."
(file-name-nondirectory file)))))
(list file fmt)))
(let (value size old-undo)
- ;; Record only one undo entry for the insertion. Inhibit point-motion and
- ;; modification hooks as with `insert-file-contents'.
- (let ((inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t))
+ ;; Record only one undo entry for the insertion.
+ ;; Inhibit modification hooks as with `insert-file-contents'.
+ (let ((inhibit-modification-hooks t))
;; Don't bind `buffer-undo-list' to t here to assert that
;; `insert-file-contents' may record whether the buffer was unmodified
;; before.
diff --git a/lisp/forms.el b/lisp/forms.el
index fdc44b5214f..b97fdbe04c8 100644
--- a/lisp/forms.el
+++ b/lisp/forms.el
@@ -1928,8 +1928,7 @@ after writing out the data."
(let ((i 0)
(here (point))
there
- (cnt 0)
- (inhibit-point-motion-hooks t))
+ (cnt 0))
(if (zerop arg)
(setq cnt 1)
@@ -1955,8 +1954,7 @@ after writing out the data."
(let ((i (length forms--markers))
(here (point))
there
- (cnt 0)
- (inhibit-point-motion-hooks t))
+ (cnt 0))
(if (zerop arg)
(setq cnt 1)
diff --git a/lisp/frame.el b/lisp/frame.el
index ae8449d0ea8..400f8a44eea 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -64,7 +64,7 @@ handles the corresponding kind of display.")
;; But that's not necessary, because the default is to have one.
;; By not specifying it here, we let an X resource specify it.
(defcustom initial-frame-alist nil
- "Alist of parameters for the initial X window frame.
+ "Alist of parameters for the initial window-system (a.k.a. \"GUI\") frame.
You can set this in your init file; for example,
(setq initial-frame-alist
@@ -77,17 +77,20 @@ If the value calls for a frame without a minibuffer, and you have
not created a minibuffer frame on your own, a minibuffer frame is
created according to `minibuffer-frame-alist'.
-You can specify geometry-related options for just the initial
-frame by setting this variable in your init file; however, they
-won't take effect until Emacs reads your init file, which happens
-after creating the initial frame. If you want the initial frame
-to have the proper geometry as soon as it appears, you need to
-use this three-step process:
+Emacs reads your main init file after creating the initial frame,
+so setting it there won't have the expected effect. Instead, you
+can set it in `early-init-file'.
+
+If you're using X, and you want (for instance) to have different
+geometries on different displays, you need to use this three-step
+process:
+
* Specify X resources to give the geometry you want.
* Set `default-frame-alist' to override these options so that they
don't affect subsequent frames.
-* Set `initial-frame-alist' in a way that matches the X resources,
- to override what you put in `default-frame-alist'."
+* Set `initial-frame-alist' in your normal init file in a way
+ that matches the X resources, to override what you put in
+ `default-frame-alist'."
:type '(repeat (cons :format "%v"
(symbol :tag "Parameter")
(sexp :tag "Value")))
@@ -1790,7 +1793,7 @@ of frames like calls to map a frame or change its visibility."
(insert (format ", DS=%sx%s" (nth 0 item) (nth 1 item))))
(insert "\n"))
((and (eq (nth 0 item) frame) (= (nth 1 item) 5))
- ;; Length 5 is an `adjust-frame-size' item.
+ ;; Length 5 is an 'adjust_frame_size' item.
(insert (format "%s (%s)" (nth 3 item) (nth 2 item)))
(setq item (nth 0 (cdr entry)))
(unless (and (= (nth 0 item) (nth 2 item))
@@ -2422,9 +2425,9 @@ It may be less than the total screen size, owing to space taken up
by window manager features (docks, taskbars, etc.). The precise
details depend on the platform and environment.
-The `source' attribute describes the source from which the information
-was obtained. On X, this may be one of: \"Gdk\", \"XRandr\", \"Xinerama\",
-or \"fallback\".
+The `source' attribute describes the source from which the
+information was obtained. On X, this may be one of: \"Gdk\",
+\"XRandR 1.5\", \"XRandr\", \"Xinerama\", or \"fallback\".
A frame is dominated by a physical monitor when either the
largest area of the frame resides in the monitor, or the monitor
@@ -2513,6 +2516,7 @@ symbols."
((eq frame-type 'pgtk)
(pgtk-device-class name))
(t (cond
+ ((not name) nil)
((string= name "Virtual core pointer")
'core-pointer)
((string= name "Virtual core keyboard")
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index 83ba72c091f..3bea1a4c1d6 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -1765,7 +1765,6 @@ Initialized from `text-mode-syntax-table'.")
`(with-current-buffer gnus-article-buffer
(save-restriction
(let ((inhibit-read-only t)
- (inhibit-point-motion-hooks t)
(case-fold-search t))
(article-narrow-to-head)
,@forms))))
@@ -1852,7 +1851,6 @@ Initialized from `text-mode-syntax-table'.")
(let ((inhibit-read-only t)
(case-fold-search t)
(max (1+ (length gnus-sorted-header-list)))
- (inhibit-point-motion-hooks t)
(cur (current-buffer))
ignored visible beg)
(save-excursion
@@ -1919,8 +1917,7 @@ always hide."
(not gnus-show-all-headers))
(save-excursion
(save-restriction
- (let ((inhibit-read-only t)
- (inhibit-point-motion-hooks t))
+ (let ((inhibit-read-only t))
(article-narrow-to-head)
(dolist (elem gnus-boring-article-headers)
(goto-char (point-min))
@@ -2567,8 +2564,7 @@ fill width."
"Decode all MIME-encoded words in the article."
(interactive nil gnus-article-mode gnus-summary-mode)
(gnus-with-article-buffer
- (let ((inhibit-point-motion-hooks t)
- (mail-parse-charset gnus-newsgroup-charset)
+ (let ((mail-parse-charset gnus-newsgroup-charset)
(mail-parse-ignored-charsets
(with-current-buffer gnus-summary-buffer
gnus-newsgroup-ignored-charsets)))
@@ -2578,7 +2574,7 @@ fill width."
"Decode charset-encoded text in the article.
If PROMPT (the prefix), prompt for a coding system to use."
(interactive "P" gnus-article-mode)
- (let ((inhibit-point-motion-hooks t) (case-fold-search t)
+ (let ((case-fold-search t)
(inhibit-read-only t)
(mail-parse-charset gnus-newsgroup-charset)
(mail-parse-ignored-charsets
@@ -2620,8 +2616,7 @@ If PROMPT (the prefix), prompt for a coding system to use."
(defun article-decode-encoded-words ()
"Remove encoded-word encoding from headers."
- (let ((inhibit-point-motion-hooks t)
- (mail-parse-charset gnus-newsgroup-charset)
+ (let ((mail-parse-charset gnus-newsgroup-charset)
(mail-parse-ignored-charsets
(save-excursion (condition-case nil
(set-buffer gnus-summary-buffer)
@@ -2668,8 +2663,7 @@ If PROMPT (the prefix), prompt for a coding system to use."
(defun article-decode-group-name ()
"Decode group names in Newsgroups, Followup-To and Xref headers."
- (let ((inhibit-point-motion-hooks t)
- (inhibit-read-only t)
+ (let ((inhibit-read-only t)
(method (gnus-find-method-for-group gnus-newsgroup-name))
regexp)
(when (and (or gnus-group-name-charset-method-alist
@@ -2699,8 +2693,7 @@ The following headers are decoded: From:, To:, Cc:, Reply-To:,
Mail-Reply-To: and Mail-Followup-To:."
(when gnus-use-idna
(save-restriction
- (let ((inhibit-point-motion-hooks t)
- (inhibit-read-only t))
+ (let ((inhibit-read-only t))
(article-narrow-to-head)
(goto-char (point-min))
(while (re-search-forward "@[^ \t\n\r,>]*\\(xn--[-A-Za-z0-9.]*\\)[ \t\n\r,>]" nil t)
@@ -3171,8 +3164,7 @@ images if any to the browser, and deletes them when exiting the group
"Remove list identifiers from the Subject header.
The `gnus-list-identifiers' variable specifies what to do."
(interactive nil gnus-article-mode)
- (let ((inhibit-point-motion-hooks t)
- (regexp (gnus-group-get-list-identifiers gnus-newsgroup-name))
+ (let ((regexp (gnus-group-get-list-identifiers gnus-newsgroup-name))
(inhibit-read-only t))
(when regexp
(save-excursion
@@ -3221,34 +3213,32 @@ always hide."
(interactive nil gnus-article-mode)
(save-excursion
(save-restriction
- (let ((inhibit-point-motion-hooks t))
- (when (gnus-parameter-banner gnus-newsgroup-name)
- (article-really-strip-banner
- (gnus-parameter-banner gnus-newsgroup-name)))
- (when gnus-article-address-banner-alist
- ;; Note that the From header is decoded here, so it is
- ;; required that the *-extract-address-components function
- ;; supports non-ASCII text.
- (let ((from (save-restriction
- (widen)
- (article-narrow-to-head)
- (mail-fetch-field "from"))))
- (when (and from
- (setq from
- (cadr (funcall gnus-extract-address-components
- from))))
- (catch 'found
- (dolist (pair gnus-article-address-banner-alist)
- (when (string-match (car pair) from)
- (throw 'found
- (article-really-strip-banner (cdr pair)))))))))))))
+ (when (gnus-parameter-banner gnus-newsgroup-name)
+ (article-really-strip-banner
+ (gnus-parameter-banner gnus-newsgroup-name)))
+ (when gnus-article-address-banner-alist
+ ;; Note that the From header is decoded here, so it is
+ ;; required that the *-extract-address-components function
+ ;; supports non-ASCII text.
+ (let ((from (save-restriction
+ (widen)
+ (article-narrow-to-head)
+ (mail-fetch-field "from"))))
+ (when (and from
+ (setq from
+ (cadr (funcall gnus-extract-address-components
+ from))))
+ (catch 'found
+ (dolist (pair gnus-article-address-banner-alist)
+ (when (string-match (car pair) from)
+ (throw 'found
+ (article-really-strip-banner (cdr pair))))))))))))
(defun article-really-strip-banner (banner)
"Strip the banner specified by the argument."
(save-excursion
(save-restriction
- (let ((inhibit-point-motion-hooks t)
- (gnus-signature-limit nil)
+ (let ((gnus-signature-limit nil)
(inhibit-read-only t))
(article-goto-body)
(cond
@@ -3307,8 +3297,7 @@ always hide."
"Remove all blank lines from the beginning of the article."
(interactive nil gnus-article-mode)
(save-excursion
- (let ((inhibit-point-motion-hooks t)
- (inhibit-read-only t))
+ (let ((inhibit-read-only t))
(when (article-goto-body)
(while (and (not (eobp))
(looking-at "[ \t]*$"))
@@ -3349,8 +3338,7 @@ Point is left at the beginning of the narrowed-to region."
"Replace consecutive blank lines with one empty line."
(interactive nil gnus-article-mode)
(save-excursion
- (let ((inhibit-point-motion-hooks t)
- (inhibit-read-only t))
+ (let ((inhibit-read-only t))
;; First make all blank lines empty.
(article-goto-body)
(while (re-search-forward "^[ \t]+$" nil t)
@@ -3368,8 +3356,7 @@ Point is left at the beginning of the narrowed-to region."
"Remove all white space from the beginning of the lines in the article."
(interactive nil gnus-article-mode)
(save-excursion
- (let ((inhibit-point-motion-hooks t)
- (inhibit-read-only t))
+ (let ((inhibit-read-only t))
(article-goto-body)
(while (re-search-forward "^[ \t]+" nil t)
(replace-match "" t t)))))
@@ -3378,8 +3365,7 @@ Point is left at the beginning of the narrowed-to region."
"Remove all white space from the end of the lines in the article."
(interactive nil gnus-article-mode)
(save-excursion
- (let ((inhibit-point-motion-hooks t)
- (inhibit-read-only t))
+ (let ((inhibit-read-only t))
(article-goto-body)
(while (re-search-forward "[ \t]+$" nil t)
(replace-match "" t t)))))
@@ -3395,37 +3381,35 @@ Point is left at the beginning of the narrowed-to region."
"Strip all blank lines."
(interactive nil gnus-article-mode)
(save-excursion
- (let ((inhibit-point-motion-hooks t)
- (inhibit-read-only t))
+ (let ((inhibit-read-only t))
(article-goto-body)
(while (re-search-forward "^[ \t]*\n" nil t)
(replace-match "" t t)))))
(defun gnus-article-narrow-to-signature ()
"Narrow to the signature; return t if a signature is found, else nil."
- (let ((inhibit-point-motion-hooks t))
- (when (gnus-article-search-signature)
- (forward-line 1)
- ;; Check whether we have some limits to what we consider
- ;; to be a signature.
- (let ((limits (if (listp gnus-signature-limit) gnus-signature-limit
- (list gnus-signature-limit)))
- limit limited)
- (while (setq limit (pop limits))
- (if (or (and (integerp limit)
- (< (- (point-max) (point)) limit))
- (and (floatp limit)
- (< (count-lines (point) (point-max)) limit))
- (and (functionp limit)
- (funcall limit))
- (and (stringp limit)
- (not (re-search-forward limit nil t))))
- () ; This limit did not succeed.
- (setq limited t
- limits nil)))
- (unless limited
- (narrow-to-region (point) (point-max))
- t)))))
+ (when (gnus-article-search-signature)
+ (forward-line 1)
+ ;; Check whether we have some limits to what we consider
+ ;; to be a signature.
+ (let ((limits (if (listp gnus-signature-limit) gnus-signature-limit
+ (list gnus-signature-limit)))
+ limit limited)
+ (while (setq limit (pop limits))
+ (if (or (and (integerp limit)
+ (< (- (point-max) (point)) limit))
+ (and (floatp limit)
+ (< (count-lines (point) (point-max)) limit))
+ (and (functionp limit)
+ (funcall limit))
+ (and (stringp limit)
+ (not (re-search-forward limit nil t))))
+ () ; This limit did not succeed.
+ (setq limited t
+ limits nil)))
+ (unless limited
+ (narrow-to-region (point) (point-max))
+ t))))
(defun gnus-article-search-signature ()
"Search the current buffer for the signature separator.
@@ -3485,8 +3469,7 @@ means show, 0 means toggle."
(defun gnus-article-show-hidden-text (type &optional _dummy)
"Show all hidden text of type TYPE.
Originally it is hide instead of DUMMY."
- (let ((inhibit-read-only t)
- (inhibit-point-motion-hooks t))
+ (let ((inhibit-read-only t))
(gnus-remove-text-properties-when
'article-type type
(point-min) (point-max)
@@ -3528,7 +3511,6 @@ possible values."
(interactive (list 'ut t) gnus-article-mode)
(let* ((case-fold-search t)
(inhibit-read-only t)
- (inhibit-point-motion-hooks t)
(visible-date (mail-fetch-field "Date"))
pos date bface eface)
(save-excursion
@@ -4351,8 +4333,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
(insert-buffer-substring gnus-original-article-buffer)
(setq items (split-string sig))
(message-narrow-to-head)
- (let ((inhibit-point-motion-hooks t)
- (case-fold-search t))
+ (let ((case-fold-search t))
;; Don't verify multiple headers.
(setq headers (mapconcat (lambda (header)
(concat header ": "
@@ -6811,16 +6792,15 @@ not have a face in `gnus-article-boring-faces'."
(boundp 'gnus-article-boring-faces)
(symbol-value 'gnus-article-boring-faces))
(save-excursion
- (let ((inhibit-point-motion-hooks t))
- (catch 'only-boring
- (while (re-search-forward "\\b\\w\\w" nil t)
- (forward-char -1)
- (when (not (seq-intersection
- (gnus-faces-at (point))
- (symbol-value 'gnus-article-boring-faces)
- #'eq))
- (throw 'only-boring nil)))
- (throw 'only-boring t))))))
+ (catch 'only-boring
+ (while (re-search-forward "\\b\\w\\w" nil t)
+ (forward-char -1)
+ (when (not (seq-intersection
+ (gnus-faces-at (point))
+ (symbol-value 'gnus-article-boring-faces)
+ #'eq))
+ (throw 'only-boring nil)))
+ (throw 'only-boring t)))))
(defun gnus-article-refer-article ()
"Read article specified by message-id around point."
@@ -8112,18 +8092,17 @@ It does this by highlighting everything after
`gnus-signature-separator' using the face `gnus-signature'."
(interactive nil gnus-article-mode gnus-summary-mode)
(gnus-with-article-buffer
- (let ((inhibit-point-motion-hooks t))
- (save-restriction
- (when (and gnus-signature-face
- (gnus-article-narrow-to-signature))
- (overlay-put (make-overlay (point-min) (point-max) nil t)
- 'face gnus-signature-face)
- (widen)
- (gnus-article-search-signature)
- (let ((start (match-beginning 0))
- (end (set-marker (make-marker) (1+ (match-end 0)))))
- (gnus-article-add-button start (1- end) 'gnus-signature-toggle
- end)))))))
+ (save-restriction
+ (when (and gnus-signature-face
+ (gnus-article-narrow-to-signature))
+ (overlay-put (make-overlay (point-min) (point-max) nil t)
+ 'face gnus-signature-face)
+ (widen)
+ (gnus-article-search-signature)
+ (let ((start (match-beginning 0))
+ (end (set-marker (make-marker) (1+ (match-end 0)))))
+ (gnus-article-add-button start (1- end) 'gnus-signature-toggle
+ end))))))
(defun gnus-button-in-region-p (b e prop)
"Say whether PROP exists in the region."
@@ -8135,8 +8114,7 @@ It does this by highlighting everything after
specified by `gnus-button-alist'."
(interactive nil gnus-article-mode gnus-summary-mode)
(gnus-with-article-buffer
- (let ((inhibit-point-motion-hooks t)
- (case-fold-search t)
+ (let ((case-fold-search t)
(alist gnus-button-alist)
beg entry regexp)
;; We skip the headers.
@@ -8292,19 +8270,18 @@ url is put as the `gnus-button-url' overlay property on the button."
(defun gnus-signature-toggle (end)
(gnus-with-article-buffer
- (let ((inhibit-point-motion-hooks t))
- (if (text-property-any end (point-max) 'article-type 'signature)
- (progn
- (gnus-delete-wash-type 'signature)
- (gnus-remove-text-properties-when
- 'article-type 'signature end (point-max)
- (cons 'article-type (cons 'signature
- gnus-hidden-properties))))
- (gnus-add-wash-type 'signature)
- (gnus-add-text-properties-when
- 'article-type nil end (point-max)
- (cons 'article-type (cons 'signature
- gnus-hidden-properties)))))
+ (if (text-property-any end (point-max) 'article-type 'signature)
+ (progn
+ (gnus-delete-wash-type 'signature)
+ (gnus-remove-text-properties-when
+ 'article-type 'signature end (point-max)
+ (cons 'article-type (cons 'signature
+ gnus-hidden-properties))))
+ (gnus-add-wash-type 'signature)
+ (gnus-add-text-properties-when
+ 'article-type nil end (point-max)
+ (cons 'article-type (cons 'signature
+ gnus-hidden-properties))))
(let ((gnus-article-mime-handle-alist-1 gnus-article-mime-handle-alist))
(gnus-set-mode-line 'article))))
@@ -8313,8 +8290,7 @@ url is put as the `gnus-button-url' overlay property on the button."
(save-excursion
(let* ((marker (car marker-and-entry))
(entry (cadr marker-and-entry))
- (regexp (car entry))
- (inhibit-point-motion-hooks t))
+ (regexp (car entry)))
(goto-char marker)
;; This is obviously true, or something bad is happening :)
;; But we need it to have the match-data
@@ -8550,17 +8526,13 @@ url is put as the `gnus-button-url' overlay property on the button."
(defvar gnus-next-page-line-format "%{%(Next page...%)%}\n")
(defvar gnus-prev-page-line-format "%{%(Previous page...%)%}\n")
-(defvar gnus-prev-page-map
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-2] #'gnus-button-prev-page)
- (define-key map "\r" #'gnus-button-prev-page)
- map))
+(defvar-keymap gnus-prev-page-map
+ "<mouse-2>" #'gnus-button-prev-page
+ "RET" #'gnus-button-prev-page)
-(defvar gnus-next-page-map
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-2] #'gnus-button-next-page)
- (define-key map "\r" #'gnus-button-next-page)
- map))
+(defvar-keymap gnus-next-page-map
+ "<mouse-2>" #'gnus-button-next-page
+ "RET" #'gnus-button-next-page)
(defun gnus-insert-prev-page-button ()
(let ((b (point)) e
diff --git a/lisp/gnus/gnus-cite.el b/lisp/gnus/gnus-cite.el
index b4d7661d742..e344b071bfd 100644
--- a/lisp/gnus/gnus-cite.el
+++ b/lisp/gnus/gnus-cite.el
@@ -341,7 +341,6 @@ Lines matching `gnus-cite-attribution-suffix' and perhaps
(let ((buffer-read-only nil)
(alist gnus-cite-prefix-alist)
(faces gnus-cite-face-list)
- (inhibit-point-motion-hooks t)
face entry prefix skip numbers number face-alist)
;; Loop through citation prefixes.
(while alist
@@ -462,7 +461,6 @@ text (i.e., computer code and the like) will not be folded."
(interactive "P" gnus-article-mode gnus-summary-mode)
(with-current-buffer gnus-article-buffer
(let ((buffer-read-only nil)
- (inhibit-point-motion-hooks t)
(marks (gnus-dissect-cited-text))
(adaptive-fill-mode nil)
(fill-column (if width (prefix-numeric-value width) fill-column)))
@@ -536,7 +534,6 @@ always hide."
(with-current-buffer gnus-article-buffer
(let ((buffer-read-only nil)
marks
- (inhibit-point-motion-hooks t)
(props (nconc (list 'article-type 'cite)
gnus-hidden-properties))
(point (point-min))
@@ -613,7 +610,6 @@ means show, nil means toggle."
(start (cadr args))
(hidden
(text-property-any beg (1- end) 'article-type 'cite))
- (inhibit-point-motion-hooks t)
buffer-read-only)
(when (or (null arg)
(zerop arg)
@@ -673,7 +669,6 @@ See also the documentation for `gnus-article-highlight-citation'."
(let ((start (point))
(atts gnus-cite-attribution-alist)
(buffer-read-only nil)
- (inhibit-point-motion-hooks t)
(hidden 0)
total)
(goto-char (point-max))
@@ -731,13 +726,12 @@ See also the documentation for `gnus-article-highlight-citation'."
(defun gnus-cite-parse-wrapper ()
;; Wrap chopped gnus-cite-parse.
(article-goto-body)
- (let ((inhibit-point-motion-hooks t))
- (save-excursion
- (gnus-cite-parse-attributions))
- (save-excursion
- (gnus-cite-parse))
- (save-excursion
- (gnus-cite-connect-attributions))))
+ (save-excursion
+ (gnus-cite-parse-attributions))
+ (save-excursion
+ (gnus-cite-parse))
+ (save-excursion
+ (gnus-cite-connect-attributions)))
(defun gnus-cite-parse ()
;; Parse and connect citation prefixes and attribution lines.
@@ -1020,8 +1014,7 @@ See also the documentation for `gnus-article-highlight-citation'."
(defun gnus-cite-add-face (number prefix face)
;; At line NUMBER, ignore PREFIX and add FACE to the rest of the line.
(when face
- (let ((inhibit-point-motion-hooks t)
- from to overlay)
+ (let (from to overlay)
(goto-char (point-min))
(when (zerop (forward-line (1- number)))
(forward-char (length prefix))
@@ -1041,7 +1034,6 @@ See also the documentation for `gnus-article-highlight-citation'."
(gnus-cite-parse-maybe nil t)
(let ((buffer-read-only nil)
(numbers (cdr (assoc prefix gnus-cite-prefix-alist)))
- (inhibit-point-motion-hooks t)
number)
(while numbers
(setq number (car numbers)
diff --git a/lisp/gnus/gnus-cus.el b/lisp/gnus/gnus-cus.el
index ddd939794dd..32c475239e5 100644
--- a/lisp/gnus/gnus-cus.el
+++ b/lisp/gnus/gnus-cus.el
@@ -36,11 +36,11 @@
(define-derived-mode gnus-custom-mode fundamental-mode "Gnus Customize"
"Major mode for editing Gnus customization buffers.
-The following commands are available:
+The following commands are available:\\<widget-keymap>
\\[widget-forward] Move to next button or editable field.
\\[widget-backward] Move to previous button or editable field.
-\\[widget-button-click] Activate button under the mouse pointer.
+\\[widget-button-click] Activate button under the mouse pointer.
\\[widget-button-press] Activate button under point.
Entry to this mode calls the value of `gnus-custom-mode-hook'
diff --git a/lisp/gnus/gnus-gravatar.el b/lisp/gnus/gnus-gravatar.el
index d64e000d70f..93b18f95555 100644
--- a/lisp/gnus/gnus-gravatar.el
+++ b/lisp/gnus/gnus-gravatar.el
@@ -87,7 +87,6 @@ callback for `gravatar-retrieve'."
(let ((real-name (car address))
(mail-address (cadr address))
(mark (point-marker))
- (inhibit-point-motion-hooks t)
(case-fold-search t))
(save-restriction
(article-narrow-to-head)
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index fcad601d0c3..e69f0857e77 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -1717,9 +1717,7 @@ already. If INFO-UNCHANGED is non-nil, dribble buffer is not updated."
(setq mode-string (substring mode-string 0 (- max-len 4))))
(prog1
(setq mode-line-buffer-identification
- (gnus-mode-line-buffer-identification
- (list (propertize mode-string
- 'face 'mode-line-buffer-id))))
+ (gnus-mode-line-buffer-identification (list mode-string)))
(set-buffer-modified-p modified))))))
(defun gnus-group-group-name ()
@@ -2423,44 +2421,37 @@ the ephemeral group."
(regexp-quote address)
"\\(?:\\'\\|[ ,>]\\)"))
(delim (concat "^" message-unix-mail-delimiter)))
- (let ((coding-system-for-write 'binary)
- (coding-system-for-read 'binary))
- (with-temp-file tmpfile
- (mm-disable-multibyte)
- (dolist (id ids)
- (let ((file (expand-file-name id (locate-user-emacs-file
- "debbugs-cache"))))
- (if (and (not gnus-plugged)
- (file-exists-p file))
- (insert-file-contents file)
- ;; Pass non-nil VISIT to avoid errors with non-nil
- ;; `url-automatic-caching' (bug#26063, bug#29008)
- ;; and immediately unvisit.
- ;; FIXME: This masks real errors!
- (url-insert-file-contents (format mbox-url id) t)
- (setq buffer-file-name nil))))
- (goto-char (point-min))
- ;; Throw an informative error early instead of passing nonsense
- ;; to `gnus-group-read-ephemeral-group' (bug#36433).
- (unless (save-excursion (re-search-forward delim nil t))
- (error "Invalid mbox format for bug IDs: %s"
- (string-join ids ", ")))
- (while (re-search-forward delim nil t)
- (narrow-to-region (point)
- (if (search-forward "\n\n" nil t)
- (1- (point))
- (point-max)))
- (unless (string-match-p address-re
- (concat (message-fetch-field "to") " "
- (message-fetch-field "cc")))
- (goto-char (point-min))
- (if (not (re-search-forward "^To:" nil t))
- (insert "To: " address "\n")
- (message-next-header)
- (skip-chars-backward "\t\n ")
- (insert ", " address)))
- (goto-char (point-max))
- (widen))))
+ (with-temp-file tmpfile
+ (mm-disable-multibyte)
+ (dolist (id ids)
+ (let ((file (expand-file-name id (locate-user-emacs-file
+ "debbugs-cache"))))
+ (if (and (not gnus-plugged)
+ (file-exists-p file))
+ (insert-file-contents-literally file)
+ (url-insert-file-contents-literally (format mbox-url id)))))
+ (goto-char (point-min))
+ ;; Throw an informative error early instead of passing nonsense
+ ;; to `gnus-group-read-ephemeral-group' (bug#36433).
+ (unless (save-excursion (re-search-forward delim nil t))
+ (error "Invalid mbox format for bug IDs: %s"
+ (string-join ids ", ")))
+ (while (re-search-forward delim nil t)
+ (narrow-to-region (point)
+ (if (search-forward "\n\n" nil t)
+ (1- (point))
+ (point-max)))
+ (unless (string-match-p address-re
+ (concat (message-fetch-field "to") " "
+ (message-fetch-field "cc")))
+ (goto-char (point-min))
+ (if (not (re-search-forward "^To:" nil t))
+ (insert "To: " address "\n")
+ (message-next-header)
+ (skip-chars-backward "\t\n ")
+ (insert ", " address)))
+ (goto-char (point-max))
+ (widen)))
(gnus-group-read-ephemeral-group
(concat "nndoc+ephemeral:bug#" (string-join ids ","))
`(nndoc ,tmpfile
@@ -2660,6 +2651,7 @@ If EXCLUDE-GROUP, do not go to that group."
(and best-point (gnus-group-group-name))))
;; Is there something like an after-point-motion-hook?
+;; FIXME: There's `cursor-sensor-mode's `cursor-sensor-functions' property.
;; (inhibit-point-motion-hooks?). Is there a tool-bar-update function?
;; (defun gnus-group-menu-bar-update ()
diff --git a/lisp/gnus/gnus-rfc1843.el b/lisp/gnus/gnus-rfc1843.el
index 9872f7b9942..da1afb672ae 100644
--- a/lisp/gnus/gnus-rfc1843.el
+++ b/lisp/gnus/gnus-rfc1843.el
@@ -40,8 +40,7 @@
(save-excursion
(save-restriction
(message-narrow-to-head)
- (let* ((inhibit-point-motion-hooks t)
- (case-fold-search t)
+ (let* ((case-fold-search t)
(ct (message-fetch-field "Content-Type" t))
(ctl (and ct (mail-header-parse-content-type ct))))
(if (and ctl (not (string-search "/" (car ctl))))
diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el
index 327dba95c07..b8f7e7a08f0 100644
--- a/lisp/gnus/gnus-search.el
+++ b/lisp/gnus/gnus-search.el
@@ -2247,11 +2247,9 @@ article came from is also searched."
(forward-line)))))
groups))
-(defvar gnus-search-minibuffer-map
- (let ((km (make-sparse-keymap)))
- (set-keymap-parent km minibuffer-local-map)
- (define-key km (kbd "TAB") #'completion-at-point)
- km))
+(defvar-keymap gnus-search-minibuffer-map
+ :parent minibuffer-local-map
+ "TAB" #'completion-at-point)
(defun gnus-search--complete-key-data ()
"Potentially return completion data for a search key or value."
diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el
index e659a648e10..315381a6dd8 100644
--- a/lisp/gnus/gnus-srvr.el
+++ b/lisp/gnus/gnus-srvr.el
@@ -829,9 +829,10 @@ claim them."
(erase-buffer))
(gnus-browse-mode)
(setq mode-line-buffer-identification
- (list
- (format
- "Gnus: %%b {%s:%s}" (car method) (cadr method))))
+ (gnus-mode-line-buffer-identification
+ (list
+ (format
+ "Gnus: %%b {%s:%s}" (car method) (cadr method)))))
(let ((buffer-read-only nil)
name
(prefix (let ((gnus-select-method orig-select-method))
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index dde60caee7e..18ba55a4391 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -6207,8 +6207,7 @@ If WHERE is `summary', the summary mode line format will be used."
;; Update the mode line.
(setq mode-line-buffer-identification
(gnus-mode-line-buffer-identification
- (list (propertize mode-string
- 'face 'mode-line-buffer-id))))
+ (list mode-string)))
(set-buffer-modified-p t))))
(defun gnus-create-xref-hashtb (from-newsgroup headers unreads)
@@ -9857,7 +9856,6 @@ If ARG is a negative number, hide the unwanted header lines."
(widen)
(article-narrow-to-head)
(let* ((inhibit-read-only t)
- (inhibit-point-motion-hooks t)
(hidden (if (numberp arg)
(>= arg 0)
(or
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index fe556b155a8..95c9539593c 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -166,9 +166,8 @@ is slower."
(require 'message)
(save-excursion
(save-restriction
- (let ((inhibit-point-motion-hooks t))
- (nnheader-narrow-to-headers)
- (message-fetch-field field)))))
+ (nnheader-narrow-to-headers)
+ (message-fetch-field field))))
(defun gnus-fetch-original-field (field)
"Fetch FIELD from the original version of the current article."
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el
index 0afd873a5df..778a46dab37 100644
--- a/lisp/gnus/gnus.el
+++ b/lisp/gnus/gnus.el
@@ -310,12 +310,15 @@ be set in `.emacs' instead."
:type 'boolean)
(defun gnus-mode-line-buffer-identification (line)
- (let ((str (car-safe line)))
+ (let* ((str (car-safe line))
+ (str (if (stringp str)
+ (car (propertized-buffer-identification str))
+ str)))
(if (or (not (fboundp 'find-image))
(not (display-graphic-p))
(not (stringp str))
(not (string-match "^Gnus:" str)))
- line
+ (list str)
(let ((load-path (append (mm-image-load-path) load-path)))
;; Add the Gnus logo.
(add-text-properties
@@ -2232,7 +2235,7 @@ Disabling the agent may result in noticeable loss of performance."
(symbol :tag "Parameter")
(sexp :tag "Value"))))
-(defcustom gnus-user-agent '(emacs gnus type)
+(defcustom gnus-user-agent '(gnus)
"Which information should be exposed in the User-Agent header.
Can be a list of symbols or a string. Valid symbols are `gnus'
@@ -2240,7 +2243,7 @@ Can be a list of symbols or a string. Valid symbols are `gnus'
addition to the Emacs version, you can add `config' (show system
configuration) or `type' (show system type). If you set it to a
string, be sure to use a valid format, see RFC 2616."
- :version "22.1"
+ :version "29.1"
:group 'gnus-message
:type '(choice (list (set :inline t
(const :value gnus :tag "Gnus version")
@@ -2250,25 +2253,6 @@ string, be sure to use a valid format, see RFC 2616."
(const :value config :tag "system configuration"))))
(string)))
-;; Convert old (< 2005-01-10) symbol type values:
-(when (symbolp gnus-user-agent)
- (setq gnus-user-agent
- (cond ((eq gnus-user-agent 'emacs-gnus-config)
- '(emacs gnus config))
- ((eq gnus-user-agent 'emacs-gnus-type)
- '(emacs gnus type))
- ((eq gnus-user-agent 'emacs-gnus)
- '(emacs gnus))
- ((eq gnus-user-agent 'gnus)
- '(gnus))
- (t gnus-user-agent)))
- (gnus-message 1 "Converted `gnus-user-agent' to `%s'." gnus-user-agent)
- (sit-for 1)
- (if (get 'gnus-user-agent 'saved-value)
- (customize-save-variable 'gnus-user-agent gnus-user-agent)
- (gnus-message 1 "Edit your init file to make this change permanent.")
- (sit-for 2)))
-
(defcustom gnus-agent-eagerly-store-articles t
"If non-nil, cache articles eagerly.
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 49a04f601f8..5e4e9854a6b 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -888,9 +888,22 @@ symbol `never', the posting is not allowed. If it is the symbol
;; FIXME: This is related to `mail-specify-envelope-from' but works
;; differently (bug#36937).
nil
- "Non-nil means don't add \"-f username\" to the sendmail command line.
-See `feedmail-sendmail-f-doesnt-sell-me-out' for an explanation
-of what the \"-f\" parameter does."
+ "Non-nil means don't add \"-f username\" to the \"sendmail\" command line.
+The \"sendmail\" program has a useful feature to let you set the
+envelope FROM address via a command line option, \"-f\".
+Unfortunately, it also has a widely disliked default behavior of
+disclosing your actual user name anyway by inserting an
+unattractive warning in the headers. It looks something like
+this:
+
+ X-Authentication-Warning: u1.example.com: niceguy set
+ sender to niceguy@example.com using -f
+
+It is possible to configure \"sendmail\" to not do this, but such a
+reconfiguration is not an option for some users.
+
+Note that this user option is mostly useful for actual \"sendmail\"
+installations, which are rare these days."
:group 'message-sending
:link '(custom-manual "(message)Mail Variables")
:type 'boolean)
@@ -2159,8 +2172,7 @@ If FIRST is non-nil, only the first value is returned.
The buffer is expected to be narrowed to just the header of the message;
see `message-narrow-to-headers-or-head'."
- (let* ((inhibit-point-motion-hooks t)
- (value (mail-fetch-field header nil (not first))))
+ (let* ((value (mail-fetch-field header nil (not first))))
(when value
(while (string-match "\n[\t ]+" value)
(setq value (replace-match " " t t value)))
@@ -3195,7 +3207,8 @@ Like `text-mode', but with these additional commands:
;;
(setq-local syntax-propertize-function #'message--syntax-propertize)
(setq-local parse-sexp-ignore-comments t)
- (setq-local message-encoded-mail-cache nil))
+ (setq-local message-encoded-mail-cache nil)
+ (setq-local image-crop-buffer-text-function #'message--update-image-crop))
(defun message-setup-fill-variables ()
"Setup message fill variables."
@@ -3551,7 +3564,12 @@ of lines before the signature intact."
(defun message-newline-and-reformat (&optional arg not-break)
"Insert four newlines, and then reformat if inside quoted text.
-Prefix arg means justify as well."
+Prefix arg means justify as well.
+
+This function tries to guess what the quote prefix is based on
+the text on the current line before point. If point is at the
+start of the line, the formatted text (if any) is filled without
+a quote prefix."
(interactive (list (if current-prefix-arg 'full)) message-mode)
(unless (message-in-body-p)
(error "This command only works in the body of the message"))
@@ -4343,10 +4361,10 @@ arguments. If METHOD is nil in this case, the return value of
the function will be inserted instead.
If the buffer already has a\"X-Message-SMTP-Method\" header,
it is left unchanged."
- :type '(alist :key-type '(choice
- (string :tag "From Address")
- (function :tag "Predicate"))
- :value-type 'string)
+ :type '(alist :key-type (choice
+ (string :tag "From Address")
+ (function :tag "Predicate"))
+ :value-type string)
:version "29.1"
:group 'message-sending)
@@ -7290,7 +7308,6 @@ specified by FUNCTIONS, if non-nil, or by the variable
(let ((cur (current-buffer))
from subject date
references message-id follow-to
- (inhibit-point-motion-hooks t)
(message-this-is-mail t)
gnus-warning)
(save-restriction
@@ -7351,7 +7368,6 @@ If TO-NEWSGROUPS, use that as the new Newsgroups line."
(let ((cur (current-buffer))
from subject date reply-to mrt mct
references message-id follow-to
- (inhibit-point-motion-hooks t)
(message-this-is-news t)
followup-to distribution newsgroups gnus-warning posted-to)
(save-restriction
@@ -8590,7 +8606,6 @@ From headers in the original article."
(let ((regexps (if (stringp message-hidden-headers)
(list message-hidden-headers)
message-hidden-headers))
- (inhibit-point-motion-hooks t)
(inhibit-modification-hooks t)
end-of-headers)
(when regexps
@@ -8909,19 +8924,26 @@ used to take the screenshot."
:max-width (truncate (* (frame-pixel-width) 0.8))
:max-height (truncate (* (frame-pixel-height) 0.8))
:scale 1)
- (format "<#part type=\"%s\" disposition=inline data-encoding=base64 raw=t>\n%s\n<#/part>"
- type
- ;; Get a base64 version of the image -- this avoids later
- ;; complications if we're auto-saving the buffer and
- ;; restoring from a file.
- (with-temp-buffer
- (set-buffer-multibyte nil)
- (insert image)
- (base64-encode-region (point-min) (point-max) t)
- (buffer-string)))
+ (message--image-part-string type image)
nil nil t)
(insert "\n\n"))
+(defun message--image-part-string (type image)
+ (format "<#part type=\"%s\" disposition=inline data-encoding=base64 raw=t>\n%s\n<#/part>"
+ type
+ ;; Get a base64 version of the image -- this avoids later
+ ;; complications if we're auto-saving the buffer and
+ ;; restoring from a file.
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert image)
+ (base64-encode-region (point-min) (point-max) t)
+ (buffer-string))))
+
+(declare-function image-crop--content-type "image-crop")
+(defun message--update-image-crop (_text image)
+ (message--image-part-string (image-crop--content-type image) image))
+
(declare-function gnus-url-unhex-string "gnus-util")
(defun message-parse-mailto-url (url)
diff --git a/lisp/gnus/mm-uu.el b/lisp/gnus/mm-uu.el
index 8646998deb9..8d314706340 100644
--- a/lisp/gnus/mm-uu.el
+++ b/lisp/gnus/mm-uu.el
@@ -194,7 +194,7 @@ This can be either \"inline\" or \"attachment\".")
nil)
(verbatim-marks
;; slrn-style verbatim marks, see
- ;; http://slrn.sourceforge.net/docs/slrn-manual-6.html#process_verbatim_marks
+ ;; https://slrn.sourceforge.net/docs/slrn-manual-6.html#process_verbatim_marks
"^#v\\+"
"^#v\\-$"
,(lambda () (mm-uu-verbatim-marks-extract 0 0))
diff --git a/lisp/gnus/nndoc.el b/lisp/gnus/nndoc.el
index cdff7c9accf..378ada62475 100644
--- a/lisp/gnus/nndoc.el
+++ b/lisp/gnus/nndoc.el
@@ -23,7 +23,7 @@
;;; Commentary:
-;; For Outlook mail boxes format, see http://mbx2mbox.sourceforge.net/
+;; For Outlook mail boxes format, see https://mbx2mbox.sourceforge.net/
;;; Code:
diff --git a/lisp/gnus/score-mode.el b/lisp/gnus/score-mode.el
index 8e27e879392..4c9d73a6e5e 100644
--- a/lisp/gnus/score-mode.el
+++ b/lisp/gnus/score-mode.el
@@ -45,13 +45,11 @@
(defvar gnus-score-edit-exit-function nil
"Function run on exit from the score buffer.")
-(defvar gnus-score-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map emacs-lisp-mode-map)
- (define-key map "\C-c\C-c" 'gnus-score-edit-exit)
- (define-key map "\C-c\C-d" 'gnus-score-edit-insert-date)
- (define-key map "\C-c\C-p" 'gnus-score-pretty-print)
- map))
+(defvar-keymap gnus-score-mode-map
+ :parent emacs-lisp-mode-map
+ "C-c C-c" #'gnus-score-edit-exit
+ "C-c C-d" #'gnus-score-edit-insert-date
+ "C-c C-p" #'gnus-score-pretty-print)
(defvar score-mode-syntax-table
(let ((table (copy-syntax-table lisp-mode-syntax-table)))
diff --git a/lisp/gnus/smime.el b/lisp/gnus/smime.el
index fd2791f5c51..7bb116d0c54 100644
--- a/lisp/gnus/smime.el
+++ b/lisp/gnus/smime.el
@@ -614,12 +614,10 @@ A string or a list of strings is returned."
(defvar smime-buffer "*SMIME*")
-(defvar smime-mode-map
- (let ((map (make-sparse-keymap)))
- (suppress-keymap map)
- (define-key map "q" 'smime-exit)
- (define-key map "f" 'smime-certificate-info)
- map))
+(defvar-keymap smime-mode-map
+ :suppress t
+ "q" #'smime-exit
+ "f" #'smime-certificate-info)
(autoload 'gnus-completing-read "gnus-util")
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index d5b576de285..eef895ae88b 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -457,7 +457,9 @@ the C sources, too."
load-path '(".el" ".elc") 'readable))))))))
(cond
- ((and (not file-name) (subrp type))
+ ((and (not file-name)
+ (subrp type)
+ (not (subr-native-elisp-p type)))
;; A built-in function. The form is from `describe-function-1'.
(if (or (get-buffer " *DOC*")
(and also-c-source
@@ -586,36 +588,43 @@ the C sources, too."
keys))
(defun help-fns--insert-menu-bindings (menus heading)
- (seq-do-indexed
- (lambda (menu i)
- (insert
- (cond ((zerop i) "")
- ((= i (1- (length menus))) " and ")
- (t ", ")))
- (let ((map (lookup-key global-map (seq-take menu 1)))
- (start (point)))
- (seq-do-indexed
- (lambda (entry level)
- (when (symbolp map)
- (setq map (symbol-function map)))
- (when-let ((elem (assq entry (cdr map))))
- (when heading
- (insert heading)
- (setq heading nil start (point)))
- (when (> level 0)
- (insert
- (if (char-displayable-p ?→)
- " → "
- " => ")))
- (if (eq (nth 1 elem) 'menu-item)
- (progn
- (insert (nth 2 elem))
- (setq map (cadddr elem)))
- (insert (nth 1 elem))
- (setq map (cddr elem)))))
- (cdr (seq-into menu 'list)))
- (put-text-property start (point) 'face 'help-key-binding)))
- menus))
+ (let ((strings nil))
+ ;; First collect all the printed representations of menus.
+ (dolist (menu menus)
+ (let ((map (lookup-key global-map (seq-take menu 1)))
+ (string nil))
+ (seq-do-indexed
+ (lambda (entry level)
+ (when (symbolp map)
+ (setq map (symbol-function map)))
+ (when-let ((elem (assq entry (cdr map))))
+ (when (> level 0)
+ (push (if (char-displayable-p ?→)
+ " → "
+ " => ")
+ string))
+ (if (eq (nth 1 elem) 'menu-item)
+ (progn
+ (push (nth 2 elem) string)
+ (setq map (cadddr elem)))
+ (push (nth 1 elem) string)
+ (setq map (cddr elem)))))
+ (cdr (seq-into menu 'list)))
+ (when string
+ (push string strings))))
+ ;; Then output them.
+ (when strings
+ (when heading
+ (insert heading))
+ (seq-do-indexed
+ (lambda (string i)
+ (insert
+ (cond ((zerop i) "")
+ ((= i (1- (length menus))) " and ")
+ (t ", "))
+ (propertize (string-join (nreverse string))
+ 'face 'help-key-binding)))
+ strings))))
(defun help-fns--compiler-macro (function)
(pcase-dolist (`(,type . ,handler)
@@ -1159,7 +1168,8 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
(add-hook 'help-fns-describe-function-functions #'help-fns--compiler-macro 100)
(defun help-fns--generalized-variable (function)
- (when (and (get function 'gv-expander)
+ (when (and (symbolp function)
+ (get function 'gv-expander)
;; Don't mention obsolete generalized variables.
(not (get function 'byte-obsolete-generalized-variable)))
(insert (format-message " `%s' is also a " function)
diff --git a/lisp/help.el b/lisp/help.el
index 92b87cf7999..3f5e57d7d5f 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -112,7 +112,7 @@ buffer.")
(define-key map "v" 'describe-variable)
(define-key map "w" 'where-is)
(define-key map "x" 'describe-command)
- (define-key map "q" 'help-quit)
+ (define-key map "q" 'help-quit-or-quick)
map)
"Keymap for characters following the Help key.")
@@ -125,11 +125,143 @@ buffer.")
(defvar help-button-cache nil)
+
+(defvar help-quick-sections
+ '(("File"
+ (save-buffers-kill-terminal . "exit")
+ (find-file . "find")
+ (write-file . "write")
+ (save-buffer . "save")
+ (save-some-buffers . "all"))
+ ("Buffer"
+ (kill-buffer . "kill")
+ (list-buffers . "list")
+ (switch-to-buffer . "switch")
+ (goto-line . "goto line")
+ (read-only-mode . "read only"))
+ ("Window"
+ (delete-window . "only other")
+ (delete-other-windows . "only this")
+ (split-window-below . "split vert.")
+ (split-window-right . "split horiz.")
+ (other-window . "other window"))
+ ("Mark & Kill"
+ (set-mark-command . "mark")
+ (kill-line . "kill line")
+ (kill-ring-save . "kill region")
+ (yank . "yank")
+ (exchange-point-and-mark . "swap"))
+ ("Projects"
+ (project-switch-project . "switch")
+ (project-find-file . "find file")
+ (project-find-regexp . "search")
+ (project-query-replace-regexp . "search & replace")
+ (project-compile . "compile"))
+ ("Misc."
+ (undo . "undo")
+ (isearch-forward . "search")
+ (isearch-backward . "reverse search")
+ (query-replace . "search & replace")
+ (fill-paragraph . "reformat"))))
+
+(declare-function prop-match-value "text-property-search" (match))
+
+;; Inspired by a mg fork (https://github.com/troglobit/mg)
+(defun help-quick ()
+ "Display a quick-help buffer."
+ (interactive)
+ (with-current-buffer (get-buffer-create "*Quick Help*")
+ (let ((inhibit-read-only t) (padding 2) blocks)
+
+ ;; Go through every section and prepare a text-rectangle to be
+ ;; inserted later.
+ (dolist (section help-quick-sections)
+ (let ((max-key-len 0) (max-cmd-len 0) keys)
+ (dolist (ent (reverse (cdr section)))
+ (catch 'skip
+ (let* ((bind (where-is-internal (car ent) nil t))
+ (key (if bind
+ (propertize
+ (key-description bind)
+ 'face 'help-key-binding)
+ (throw 'skip nil))))
+ (setq max-cmd-len (max (length (cdr ent)) max-cmd-len)
+ max-key-len (max (length key) max-key-len))
+ (push (list key (cdr ent) (car ent)) keys))))
+ (when keys
+ (let ((fmt (format "%%-%ds %%-%ds%s" max-key-len max-cmd-len
+ (make-string padding ?\s)))
+ (width (+ max-key-len 1 max-cmd-len padding)))
+ (push `(,width
+ ,(propertize
+ (concat
+ (car section)
+ (make-string (- width (length (car section))) ?\s))
+ 'face 'bold)
+ ,@(mapcar (lambda (ent)
+ (format fmt
+ (propertize
+ (car ent)
+ 'quick-help-cmd
+ (caddr ent))
+ (cadr ent)))
+ keys))
+ blocks)))))
+
+ ;; Insert each rectangle in order until they don't fit into the
+ ;; frame any more, in which case the next sections are inserted
+ ;; in a new "line".
+ (erase-buffer)
+ (dolist (block (nreverse blocks))
+ (when (> (+ (car block) (current-column)) (frame-width))
+ (goto-char (point-max))
+ (newline 2))
+ (save-excursion
+ (insert-rectangle (cdr block)))
+ (end-of-line))
+ (delete-trailing-whitespace)
+
+ (save-excursion
+ (goto-char (point-min))
+ (while-let ((match (text-property-search-forward 'quick-help-cmd)))
+ (make-text-button (prop-match-beginning match)
+ (prop-match-end match)
+ 'mouse-face 'highlight
+ 'button t
+ 'keymap button-map
+ 'action #'describe-symbol
+ 'button-data (prop-match-value match)))))
+
+ (help-mode)
+
+ ;; Display the buffer at the bottom of the frame...
+ (with-selected-window (display-buffer-at-bottom (current-buffer) '())
+ ;; ... mark it as dedicated to prevent focus from being stolen
+ (set-window-dedicated-p (selected-window) t)
+ ;; ... and shrink it immediately.
+ (fit-window-to-buffer))
+ (message
+ (substitute-command-keys "Toggle the quick help buffer using \\[help-quit-or-quick]."))))
+
+(defalias 'cheat-sheet #'help-quick)
+
(defun help-quit ()
"Just exit from the Help command's command loop."
(interactive)
nil)
+(defun help-quit-or-quick ()
+ "Call `help-quit' or `help-quick' depending on the context."
+ (interactive)
+ (cond
+ (help-buffer-under-preparation
+ ;; FIXME: There should be a better way to detect if we are in the
+ ;; help command loop.
+ (help-quit))
+ ((and-let* ((window (get-buffer-window "*Quick Help*")))
+ (quit-window t window)))
+ ((help-quick))))
+
(defvar help-return-method nil
"What to do to \"exit\" the help buffer.
This is a list
@@ -279,6 +411,7 @@ Do not call this in the scope of `with-help-window'."
("describe-package" "Describe a specific Emacs package")
""
("help-with-tutorial" "Start the Emacs tutorial")
+ ("help-quick-or-quit" "Display the quick help buffer.")
("view-echo-area-messages"
"Show recent messages (from echo area)")
("view-lossage" ,(format "Show last %d input keystrokes (lossage)"
@@ -1204,7 +1337,16 @@ Otherwise, return a new string."
(delete-char 2)
(let* ((fun (intern (buffer-substring (point) (1- end-point))))
(key (with-current-buffer orig-buf
- (where-is-internal fun keymap t))))
+ (where-is-internal fun
+ (and keymap
+ (list keymap))
+ t))))
+ ;; If we're looking in a particular keymap which has
+ ;; no binding, then we need to redo the lookup, with
+ ;; the global map as well this time.
+ (when (and (not key) keymap)
+ (setq key (with-current-buffer orig-buf
+ (where-is-internal fun keymap t))))
(if (not key)
;; Function is not on any key.
(let ((op (point)))
diff --git a/lisp/hexl.el b/lisp/hexl.el
index 7f965486eae..b8d25bfb1f0 100644
--- a/lisp/hexl.el
+++ b/lisp/hexl.el
@@ -687,7 +687,7 @@ If there is no byte at the target address move to the last byte in that line."
(defun hexl-beginning-of-buffer (arg)
"Move to the beginning of the hexl buffer.
-Leaves `hexl-mark' at previous position.
+Leaves mark at previous position.
With prefix arg N, puts point N bytes of the way from the true beginning."
(interactive "p")
(push-mark)
diff --git a/lisp/hilit-chg.el b/lisp/hilit-chg.el
index 4832dd9023a..00748e12da9 100644
--- a/lisp/hilit-chg.el
+++ b/lisp/hilit-chg.el
@@ -118,7 +118,6 @@
;;
;; Other interactive functions (that could be bound if desired):
;; `highlight-changes-mode'
-;; `highlight-changes-toggle-visibility'
;; `highlight-changes-remove-highlight'
;; `highlight-compare-with-file'
;; `highlight-compare-buffers'
diff --git a/lisp/hl-line.el b/lisp/hl-line.el
index e5ca6819f0d..87bea1017f1 100644
--- a/lisp/hl-line.el
+++ b/lisp/hl-line.el
@@ -154,6 +154,13 @@ non-selected window. Hl-Line mode uses the function
When `hl-line-sticky-flag' is nil, Hl-Line mode highlights the
line about point in the selected window only."
:group 'hl-line
+ ;; If the global mode is switched on, then `M-x hl-line-mode' should
+ ;; switch the mode off in this buffer.
+ (when (and global-hl-line-mode
+ (eq arg 'toggle))
+ (setq hl-line-mode nil)
+ (setq-local global-hl-line-mode nil)
+ (global-hl-line-unhighlight))
(if hl-line-mode
(progn
;; In case `kill-all-local-variables' is called.
diff --git a/lisp/htmlfontify.el b/lisp/htmlfontify.el
index b1fdbd2c4a3..34092b1417e 100644
--- a/lisp/htmlfontify.el
+++ b/lisp/htmlfontify.el
@@ -1539,33 +1539,13 @@ See also `hfy-html-enkludge-buffer'."
(if (get-text-property (match-beginning 0) 'hfy-quoteme)
(replace-match (hfy-html-quote (match-string 1))) )) ))
-;; Borrowed from font-lock.el
-(defmacro hfy-save-buffer-state (varlist &rest body)
- "Bind variables according to VARLIST and eval BODY restoring buffer state.
-Do not record undo information during evaluation of BODY."
- (declare (indent 1) (debug let))
- (let ((modified (make-symbol "modified")))
- `(let* ,(append varlist
- `((,modified (buffer-modified-p))
- (buffer-undo-list t)
- (inhibit-read-only t)
- (inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t)
- deactivate-mark
- buffer-file-name
- buffer-file-truename))
- (progn
- ,@body)
- (unless ,modified
- (restore-buffer-modified-p nil)))))
-
(defun hfy-mark-trailing-whitespace ()
"Tag trailing whitespace with a hfy property if it is currently highlighted."
(when show-trailing-whitespace
(let ((inhibit-read-only t))
(save-excursion
(goto-char (point-min))
- (hfy-save-buffer-state nil
+ (with-silent-modifications
(while (re-search-forward "[ \t]+$" nil t)
(put-text-property (match-beginning 0) (match-end 0)
'hfy-show-trailing-whitespace t)))))))
@@ -1573,7 +1553,7 @@ Do not record undo information during evaluation of BODY."
(defun hfy-unmark-trailing-whitespace ()
"Undo the effect of `hfy-mark-trailing-whitespace'."
(when show-trailing-whitespace
- (hfy-save-buffer-state nil
+ (with-silent-modifications
(remove-text-properties (point-min) (point-max)
'(hfy-show-trailing-whitespace nil)))))
diff --git a/lisp/ielm.el b/lisp/ielm.el
index 4a10c002976..fd41afa2437 100644
--- a/lisp/ielm.el
+++ b/lisp/ielm.el
@@ -474,11 +474,11 @@ nonempty, then flushes the buffer."
;;; Input fontification
-(defcustom ielm-comint-fl-enable t
+(defcustom ielm-fontify-input-enable t
"Enable fontification of input in ielm buffers.
This variable only has effect when creating an ielm buffer. Use
-the command `comint-fl-mode' to toggle fontification of input in
-an already existing ielm buffer."
+the command `comint-fontify-input-mode' to toggle fontification
+of input in an already existing ielm buffer."
:type 'boolean
:safe 'booleanp
:version "29.1")
@@ -491,7 +491,7 @@ and syntax highlighting are set up with `emacs-lisp-mode'. In
addition to `comint-indirect-setup-hook', run this hook with the
indirect buffer as the current buffer after its setup is done.
This can be used to further customize fontification and other
-behaviour of the indirect buffer."
+behavior of the indirect buffer."
:type 'boolean
:safe 'booleanp
:version "29.1")
@@ -556,8 +556,8 @@ Customized bindings may be defined in `ielm-map', which currently contains:
:syntax-table emacs-lisp-mode-syntax-table
:after-hook
(and (null comint-use-prompt-regexp)
- ielm-comint-fl-enable
- (comint-fl-mode))
+ ielm-fontify-input-enable
+ (comint-fontify-input-mode))
(setq comint-prompt-regexp (concat "^" (regexp-quote ielm-prompt)))
(setq-local paragraph-separate "\\'")
diff --git a/lisp/image-file.el b/lisp/image-file.el
index 0ed88e8e749..63f9e1100c6 100644
--- a/lisp/image-file.el
+++ b/lisp/image-file.el
@@ -91,9 +91,10 @@ the variable is set using \\[customize]."
"\\'"))))
(mapconcat
#'identity
- (delq nil (list exts-regexp
- image-file-name-regexps
- (car (rassq 'imagemagick image-type-file-name-regexps))))
+ (delq nil
+ (nconc (list exts-regexp
+ (car (rassq 'imagemagick image-type-file-name-regexps)))
+ (ensure-list image-file-name-regexps)))
"\\|")))
diff --git a/lisp/image-mode.el b/lisp/image-mode.el
index 9485f1e0060..bd208fbad46 100644
--- a/lisp/image-mode.el
+++ b/lisp/image-mode.el
@@ -498,8 +498,8 @@ image as text, when opening such images in `image-mode'."
"s s" #'image-transform-set-scale
"s r" #'image-transform-set-rotation
"s m" #'image-transform-set-smoothing
- "s o" #'image-transform-original
- "s 0" #'image-transform-reset
+ "s o" #'image-transform-reset-to-original
+ "s 0" #'image-transform-reset-to-initial
;; Multi-frame keys
"RET" #'image-toggle-animation
@@ -523,6 +523,9 @@ image as text, when opening such images in `image-mode'."
"S-SPC" #'image-scroll-down
"DEL" #'image-scroll-down
+ ;; Misc
+ "W" #'image-mode-wallpaper-set
+
;; Remapped
"<remap> <forward-char>" #'image-forward-hscroll
"<remap> <backward-char>" #'image-backward-hscroll
@@ -567,9 +570,9 @@ image as text, when opening such images in `image-mode'."
:help "Set rotation angle of the image"]
["Set Smoothing..." image-transform-set-smoothing
:help "Toggle smoothing"]
- ["Original Size" image-transform-original
+ ["Original Size" image-transform-reset-to-original
:help "Reset image to actual size"]
- ["Reset to Default Size" image-transform-reset
+ ["Reset to Default Size" image-transform-reset-to-initial
:help "Reset all image transformations to initial size"]
"--"
["Show Thumbnails"
@@ -663,6 +666,9 @@ Key bindings:
"(New file)")
"Empty buffer"))
(image-mode--display)
+ (setq-local image-crop-buffer-text-function
+ ;; Use the binary image data directly for the buffer text.
+ (lambda (_text image) image))
;; Ensure that we recognize externally parsed image formats in
;; commands like `n'.
(when image-use-external-converter
@@ -1051,7 +1057,13 @@ Otherwise, display the image by calling `image-mode'."
(defun image-fit-to-window (window)
"Adjust size of image to display it exactly in WINDOW boundaries."
- (when (window-live-p window)
+ (when (and (window-live-p window)
+ ;; Don't resize anything if we're in the minibuffer
+ ;; (which may transitively change the window sizes if you
+ ;; hit TAB, for instance).
+ (not (minibuffer-window-active-p (selected-window)))
+ ;; Don't resize if there's a message in the echo area.
+ (not (current-message)))
(with-current-buffer (window-buffer window)
(when (derived-mode-p 'image-mode)
(let ((spec (image-get-display-property)))
@@ -1262,7 +1274,7 @@ If N is negative, go to the previous file."
(save-window-excursion
(switch-to-buffer (cdr buffer) t t)
(cl-case (car buffer)
- ('dired
+ (dired
(dired-goto-file file)
(let (found)
(while (and (not found)
@@ -1280,9 +1292,9 @@ If N is negative, go to the previous file."
;; If we didn't find a next/prev file, then restore
;; point.
(dired-goto-file file))))
- ('archive
+ (archive
(setq next (archive-next-file-displayer file regexp n)))
- ('tar
+ (tar
(setq next (tar-next-file-displayer file regexp n))))))
next))
@@ -1358,16 +1370,6 @@ If no such buffer exists, it will be opened."
(message "%s%s" (capitalize (substring string 0 1))
(substring string 1)))))
-(defun image-mode--images-in-directory (file)
- (let* ((dir (file-name-directory buffer-file-name))
- (files (directory-files dir nil
- (image-file-name-regexp) t)))
- ;; Add the current file to the list of images if necessary, in
- ;; case it does not match `image-file-name-regexp'.
- (unless (member file files)
- (push file files))
- (sort files 'string-lessp)))
-
;;; Support for bookmark.el
(declare-function bookmark-make-record-default
@@ -1387,7 +1389,18 @@ If no such buffer exists, it will be opened."
(prog1 (bookmark-default-handler bmk)
(when (not (string= image-type (bookmark-prop-get bmk 'image-type)))
(image-toggle-display))))
+
+;;; Setting the wallpaper
+
+(defun image-mode-wallpaper-set ()
+ "Set the desktop background to the current image.
+This uses `wallpaper-set' (which see)."
+ (interactive nil image-mode)
+ (wallpaper-set buffer-file-name))
+
+
+;;; Image transformation
(defsubst image-transform-width (width height)
"Return the bounding box width of a rotated WIDTH x HEIGHT rectangle.
@@ -1593,14 +1606,14 @@ ROTATION should be in degrees."
(setq image--transform-smoothing smoothing)
(image-toggle-display-image))
-(defun image-transform-original ()
+(defun image-transform-reset-to-original ()
"Display the current image with the original (actual) size and rotation."
(interactive nil image-mode)
(setq image-transform-resize nil
image-transform-scale 1)
(image-toggle-display-image))
-(defun image-transform-reset ()
+(defun image-transform-reset-to-initial ()
"Display the current image with the default (initial) size and rotation."
(interactive nil image-mode)
(setq image-transform-resize image-auto-resize
@@ -1609,6 +1622,20 @@ ROTATION should be in degrees."
image--transform-smoothing nil)
(image-toggle-display-image))
+(defun image-mode--images-in-directory (file)
+ (declare (obsolete nil "29.1"))
+ (let* ((dir (file-name-directory buffer-file-name))
+ (files (directory-files dir nil
+ (image-file-name-regexp) t)))
+ ;; Add the current file to the list of images if necessary, in
+ ;; case it does not match `image-file-name-regexp'.
+ (unless (member file files)
+ (push file files))
+ (sort files 'string-lessp)))
+
+(define-obsolete-function-alias 'image-transform-original #'image-transform-reset-to-original "29.1")
+(define-obsolete-function-alias 'image-transform-reset #'image-transform-reset-to-initial "29.1")
+
(provide 'image-mode)
;;; image-mode.el ends here
diff --git a/lisp/image.el b/lisp/image.el
index 9311125450a..b6817d3fda3 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -174,12 +174,15 @@ or \"ffmpeg\") is installed."
(defvar-keymap image-map
:doc "Map put into text properties on images."
- "-" #'image-decrease-size
- "+" #'image-increase-size
- "r" #'image-rotate
- "o" #'image-save
- "h" #'image-flip-horizontally
- "v" #'image-flip-vertically
+ "i" (define-keymap
+ "-" #'image-decrease-size
+ "+" #'image-increase-size
+ "r" #'image-rotate
+ "o" #'image-save
+ "c" #'image-crop
+ "x" #'image-cut
+ "h" #'image-flip-horizontally
+ "v" #'image-flip-vertically)
"C-<wheel-down>" #'image-mouse-decrease-size
"C-<mouse-5>" #'image-mouse-decrease-size
"C-<wheel-up>" #'image-mouse-increase-size
@@ -474,8 +477,9 @@ must be available."
;;;###autoload
(defun create-image (file-or-data &optional type data-p &rest props)
- "Create an image.
-FILE-OR-DATA is an image file name or image data.
+ "Create an image from FILE-OR-DATA.
+FILE-OR-DATA is an image file name or image data. If it is a relative
+file name, the function will look for it along `image-load-path'.
Optional TYPE is a symbol describing the image type. If TYPE is omitted
or nil, try to determine the image type from its first few bytes
@@ -492,11 +496,7 @@ automatically scaled up in proportion to the default font.
Value is the image created, or nil if images of type TYPE are not supported.
-Images should not be larger than specified by `max-image-size'.
-
-Image file names that are not absolute are searched for in the
-\"images\" sub-directory of `data-directory' and
-`x-bitmap-file-path' (in that order)."
+Images should not be larger than specified by `max-image-size'."
(let ((data-format
;; Pass the image format, if any, if this is data.
(and data-p (or (plist-get props :format) t))))
@@ -1152,41 +1152,43 @@ has no effect."
(imagemagick-register-types)
+(defvar-keymap image--repeat-map
+ "+" #'image-increase-size
+ "-" #'image-decrease-size
+ "r" #'image-rotate)
+
(defun image-increase-size (&optional n position)
"Increase the image size by a factor of N.
If N is 3, then the image size will be increased by 30%. The
default is 20%."
(interactive "P")
+ (image--delayed-change-size (if n
+ (1+ (/ (prefix-numeric-value n) 10.0))
+ 1.2)
+ position)
+ (set-transient-map image--repeat-map nil nil
+ "Use %k for further adjustments"))
+
+(defun image--delayed-change-size (size position)
;; Wait for a bit of idle-time before actually performing the change,
;; so as to batch together sequences of closely consecutive size changes.
;; `image--change-size' just changes one value in a plist. The actual
;; image resizing happens later during redisplay. So if those
;; consecutive calls happen without any redisplay between them,
;; the costly operation of image resizing should happen only once.
- (run-with-idle-timer 0.3 nil
- #'image--change-size
- (if n
- (1+ (/ (prefix-numeric-value n) 10.0))
- 1.2)
- position))
+ (run-with-idle-timer 0.3 nil #'image--change-size size position))
(defun image-decrease-size (&optional n position)
"Decrease the image size by a factor of N.
If N is 3, then the image size will be decreased by 30%. The
default is 20%."
(interactive "P")
- ;; Wait for a bit of idle-time before actually performing the change,
- ;; so as to batch together sequences of closely consecutive size changes.
- ;; `image--change-size' just changes one value in a plist. The actual
- ;; image resizing happens later during redisplay. So if those
- ;; consecutive calls happen without any redisplay between them,
- ;; the costly operation of image resizing should happen only once.
- (run-with-idle-timer 0.3 nil
- #'image--change-size
- (if n
- (- 1 (/ (prefix-numeric-value n) 10.0))
- 0.8)
- position))
+ (image--delayed-change-size (if n
+ (- 1 (/ (prefix-numeric-value n) 10.0))
+ 0.8)
+ position)
+ (set-transient-map image--repeat-map nil nil
+ "Use %k for further adjustments"))
(defun image-mouse-increase-size (&optional event)
"Increase the image size using the mouse."
@@ -1271,7 +1273,9 @@ rotations by only multiples of 90 degrees."
(or angle 90))
;; We don't want to exceed 360 degrees rotation,
;; because it's not seen as valid in Exif data.
- 360)))))
+ 360))))
+ (set-transient-map image--repeat-map nil nil
+ "Use %k for further adjustments"))
(defun image-save ()
"Save the image under point.
diff --git a/lisp/image/exif.el b/lisp/image/exif.el
index b25968af536..53d2074ed71 100644
--- a/lisp/image/exif.el
+++ b/lisp/image/exif.el
@@ -271,13 +271,13 @@ VALUE is an integer representing BYTES characters."
"Do type-based post-processing of the value."
(cl-case type
;; Chop off trailing zero byte.
- ('ascii (substring value 0 (1- (length value))))
- ('rational (with-temp-buffer
- (set-buffer-multibyte nil)
- (insert value)
- (goto-char (point-min))
- (cons (exif--read-number 4 le)
- (exif--read-number 4 le))))
+ (ascii (substring value 0 (1- (length value))))
+ (rational (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert value)
+ (goto-char (point-min))
+ (cons (exif--read-number 4 le)
+ (exif--read-number 4 le))))
(otherwise value)))
(defun exif--read-chunk (bytes)
diff --git a/lisp/image/image-crop.el b/lisp/image/image-crop.el
new file mode 100644
index 00000000000..7fbbf85f939
--- /dev/null
+++ b/lisp/image/image-crop.el
@@ -0,0 +1,452 @@
+;;; image-crop.el --- Image Cropping -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Keywords: multimedia
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package provides an interface for cropping images
+;; interactively, but relies on external programs to do the actual
+;; modifications to files.
+
+;;; Code:
+
+(require 'svg)
+(require 'text-property-search)
+(eval-when-compile (require 'subr-x))
+
+(defvar image-scaling-factor)
+(declare-function image-property "image.el" (image property))
+(declare-function image-size "image.c" (spec &optional pixels frame))
+(declare-function imagep "image.c" (spec))
+
+(defgroup image-crop ()
+ "Image cropping."
+ :group 'image)
+
+(defvar image-crop-exif-rotate nil
+ "If non-nil, rotate images by updating exif data.
+If nil, rotate the images \"physically\".")
+
+(defcustom image-crop-resize-command '("convert" "-resize" "%wx" "-" "%f:-")
+ "Command to resize an image.
+The following `format-spec' elements are allowed:
+
+%w: Width.
+%f: Result file type."
+ :type '(repeat string)
+ :version "29.1")
+
+(defcustom image-crop-cut-command '("convert" "-draw" "rectangle %l,%t %r,%b"
+ "-fill" "%c"
+ "-" "%f:-")
+ "Command to cut a rectangle out of an image.
+
+The following `format-spec' elements are allowed:
+%l: Left.
+%t: Top.
+%r: Right.
+%b: Bottom.
+%c: Color.
+%f: Result file type."
+ :type '(repeat string)
+ :version "29.1")
+
+(defcustom image-crop-crop-command '("convert" "+repage" "-crop" "%wx%h+%l+%t"
+ "-" "%f:-")
+ "Command to crop an image.
+
+The following `format-spec' elements are allowed:
+%l: Left.
+%t: Top.
+%w: Width.
+%h: Height.
+%f: Result file type."
+ :type '(repeat string)
+ :version "29.1")
+
+(defcustom image-crop-rotate-command '("convert" "-rotate" "%r" "-" "%f:-")
+ "Command to rotate an image.
+
+The following `format-spec' elements are allowed:
+%r: Rotation (in degrees).
+%f: Result file type."
+ :type '(repeat string)
+ :version "29.1")
+
+(defvar image-crop-buffer-text-function #'image-crop--default-buffer-text
+ "Function to return the buffer text for the cropped image.
+After cropping an image, the displayed image will be updated to
+show the cropped image in the buffer. Different modes will have
+different ways to represent this image data in a buffer. For
+instance, an HTML-based mode might want to represent the image
+with <img src=\"data:...base64...\">, but that's up to the mode.
+
+The default action is to not alter the buffer text at all.
+
+The function is called with two arguments: The first is the
+original buffer text, and the second parameter is the cropped
+image data.")
+
+(defcustom image-cut-color "black"
+ "Color to use for the rectangle cut from the image."
+ :type 'string
+ :version "29.1")
+
+;;;###autoload
+(defun image-cut (&optional color)
+ "Cut a rectangle from the image under point, filling it with COLOR.
+COLOR defaults to the value of `image-cut-color'.
+Interactively, with prefix argument, prompt for COLOR to use."
+ (interactive (list (and current-prefix-arg (read-color "Use color: "))))
+ (image-crop (if (zerop (length color)) image-cut-color color)))
+
+;;;###autoload
+(defun image-crop (&optional cut)
+ "Crop the image under point.
+If CUT is non-nil, remove a rectangle from the image instead of
+cropping the image. In that case CUT should be the name of a
+color to fill the rectangle.
+
+While cropping the image, the following key bindings are available:
+
+`q': Exit without changing anything.
+`RET': Crop/cut the image.
+`m': Make mouse movements move the rectangle instead of altering the
+ rectangle shape.
+`s': Same as `m', but make the rectangle into a square first.
+
+After cropping an image, you can save it by `M-x image-save' or
+\\<image-map>\\[image-save] when point is over the image."
+ (interactive)
+ (unless (image-type-available-p 'svg)
+ (error "SVG support is needed to crop images"))
+ (unless (executable-find (car image-crop-crop-command))
+ (error "Couldn't find %s command to crop the image"
+ (car image-crop-crop-command)))
+ (let ((image (get-text-property (point) 'display)))
+ (unless (imagep image)
+ (user-error "No image under point"))
+ (when (overlays-at (point))
+ (user-error "Can't edit images that have overlays"))
+ ;; We replace the image under point with an SVG image that looks
+ ;; just like that image. That allows us to draw lines over it.
+ ;; At the end, we replace that SVG with a cropped version of the
+ ;; original image.
+ (let* ((data (cl-getf (cdr image) :data))
+ (undo-handle (prepare-change-group))
+ (type (cond
+ ((cl-getf (cdr image) :format)
+ (format "%s" (cl-getf (cdr image) :format)))
+ (data
+ (image-crop--content-type data))))
+ (image-scaling-factor 1)
+ (orig-point (point))
+ (size (image-size image t))
+ (svg (svg-create (car size) (cdr size)
+ :xmlns:xlink "http://www.w3.org/1999/xlink"
+ :stroke-width 5))
+ ;; We want to get the original text that's covered by the
+ ;; image so that we can restore it.
+ (image-start
+ (save-excursion
+ (let ((match (text-property-search-backward 'display image)))
+ (if match
+ (prop-match-end match)
+ (point-min)))))
+ (image-end
+ (save-excursion
+ (let ((match (text-property-search-forward 'display image)))
+ (if match
+ (prop-match-beginning match)
+ (point-max)))))
+ (text (buffer-substring image-start image-end))
+ (inhibit-read-only t)
+ orig-data svg-end)
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (if (null data)
+ (insert-file-contents-literally (cl-getf (cdr image) :file))
+ (insert data))
+ (let ((image-crop-exif-rotate nil))
+ (image-crop--possibly-rotate-buffer image))
+ (setq orig-data (buffer-string))
+ (setq type (image-crop--content-type orig-data))
+ (image-crop--process image-crop-resize-command
+ `((?w . 600)
+ (?f . ,(cadr (split-string type "/")))))
+ (setq data (buffer-string)))
+ (svg-embed svg data type t
+ :width (car size)
+ :height (cdr size))
+ (with-buffer-unmodified-if-unchanged
+ (delete-region image-start image-end)
+ (svg-insert-image svg)
+ (setq svg-end (point))
+ (let ((area (condition-case _
+ (save-excursion
+ (forward-line 1)
+ (image-crop--crop-image-1
+ svg (if cut "cut" "crop")))
+ (quit nil))))
+ (message (substitute-command-keys
+ "Type \\[image-save] to save %s image to file")
+ (if cut "cut" "cropped"))
+ (delete-region image-start svg-end)
+ (if area
+ (image-crop--crop-image-update
+ area orig-data size type cut text)
+ ;; If the user didn't complete the crop, re-insert the
+ ;; original image (and text).
+ (insert text)
+ (goto-char orig-point))
+ (undo-amalgamate-change-group undo-handle))))))
+
+(defun image-crop--crop-image-update (area data size type cut text)
+ (let* ((image-scaling-factor 1)
+ (osize (image-size (create-image data nil t) t))
+ (factor (/ (float (car osize)) (car size)))
+ ;; width x height + left + top
+ (width (abs (truncate (* factor (- (cl-getf area :right)
+ (cl-getf area :left))))))
+ (height (abs (truncate (* factor (- (cl-getf area :bottom)
+ (cl-getf area :top))))))
+ (left (truncate (* factor (min (cl-getf area :left)
+ (cl-getf area :right)))))
+ (top (truncate (* factor (min (cl-getf area :top)
+ (cl-getf area :bottom))))))
+ (image-crop--insert-image-data
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert data)
+ (if cut
+ (image-crop--process image-crop-cut-command
+ `((?l . ,left)
+ (?t . ,top)
+ (?r . ,(+ left width))
+ (?b . ,(+ top height))
+ (?c . ,cut)
+ (?f . ,(cadr (split-string type "/")))))
+ (image-crop--process image-crop-crop-command
+ `((?l . ,left)
+ (?t . ,top)
+ (?w . ,width)
+ (?h . ,height)
+ (?f . ,(cadr (split-string type "/"))))))
+ (buffer-string))
+ text)))
+
+(defun image-crop--width (area)
+ (- (plist-get area :right) (plist-get area :left)))
+
+(defun image-crop--height (area)
+ (- (plist-get area :bottom) (plist-get area :top)))
+
+(defun image-crop--crop-image-1 (svg op)
+ (track-mouse
+ (cl-loop
+ with prompt = (format
+ (substitute-command-keys
+ "Select area for %s (click \\`mouse-1' and drag)")
+ op)
+ and state = 'begin
+ and area = (list :left 0
+ :top 0
+ :right 0
+ :bottom 0)
+ and corner = nil
+ for event = (read-event prompt)
+ do (cond
+ ;; Go to "square" mode.
+ ((eql event ?s)
+ (setq state 'move-unclick
+ prompt (format "Move square for %s" op))
+ (let ((size (min (image-crop--width area) (image-crop--height area))))
+ (setf (plist-get area :right) (+ (plist-get area :left) size)
+ (plist-get area :bottom) (+ (plist-get area :top) size))))
+ ;; Go to "move" move.
+ ((eql event ?m)
+ (setq state 'move-unclick
+ prompt (format "Move for %s" op)))
+ ;; We have a (relevant) mouse event.
+ ((and (consp event)
+ (consp (cadr event))
+ (nth 7 (cadr event))
+ ;; Only do things if point is over the SVG being
+ ;; tracked.
+ (eq (cl-getf (cdr (nth 7 (cadr event))) :type)
+ 'svg))
+ (let ((pos (nth 8 (cadr event))))
+ (cl-case state
+ (begin
+ (cond
+ ((eq (car event) 'down-mouse-1)
+ (setq state 'stretch
+ prompt (format "Stretch to end point for %s" op))
+ (setf (cl-getf area :left) (car pos)
+ (cl-getf area :top) (cdr pos)
+ (cl-getf area :right) (car pos)
+ (cl-getf area :bottom) (cdr pos)))))
+ (stretch
+ (cond
+ ((eq (car event) 'mouse-movement)
+ (setf (cl-getf area :right) (car pos)
+ (cl-getf area :bottom) (cdr pos)))
+ ((memq (car event) '(mouse-1 drag-mouse-1))
+ (setq state 'corner
+ prompt (format
+ (substitute-command-keys
+ (concat
+ "Type \\`RET' to %s, or click and drag "
+ "\\`mouse-1' to adjust corners"))
+ op)))))
+ (corner
+ (cond
+ ((eq (car event) 'down-mouse-1)
+ ;; Find out what corner we're close to.
+ (setq corner (image-crop--find-corner
+ area pos
+ '((:left :top)
+ (:left :bottom)
+ (:right :top)
+ (:right :bottom))))
+ (when corner
+ (setq state 'adjust
+ prompt (format
+ (substitute-command-keys
+ "Adjusting %s area (release \\`mouse-1' to confirm)")
+ op))))))
+ (adjust
+ (cond
+ ((memq (car event) '(mouse drag-mouse-1))
+ (setq state 'corner
+ prompt (format "Choose corner to adjust area for %s" op)))
+ ((eq (car event) 'mouse-movement)
+ (setf (cl-getf area (car corner)) (car pos)
+ (cl-getf area (cadr corner)) (cdr pos)))))
+ (move-unclick
+ (cond
+ ((eq (car event) 'down-mouse-1)
+ (setq state 'move-click
+ prompt (format "Move for %s" op)))))
+ (move-click
+ (cond
+ ((eq (car event) 'mouse-movement)
+ (setf (cl-getf area :right)
+ (+ (car pos) (image-crop--width area)))
+ (setf (cl-getf area :left) (car pos))
+ (setf (cl-getf area :bottom)
+ (+ (cdr pos) (image-crop--height area)))
+ (setf (cl-getf area :top) (cdr pos)))
+ ((memq (car event) '(mouse-1 drag-mouse-1))
+ (setq state 'move-unclick
+ prompt (format "Click to move for %s" op)))))))))
+ do (svg-rectangle svg (cl-getf area :left) (cl-getf area :top)
+ (image-crop--width area) (image-crop--height area)
+ :stroke-color "red" :stroke-width 2
+ :fill-opacity 0.3 :fill "black" :id "rect")
+ while (not (member event '(return ?q)))
+ finally (return (and (eq event 'return)
+ area)))))
+
+(defun image-crop--find-corner (area pos corners)
+ (cl-loop for corner in corners
+ ;; We accept 10 pixels off.
+ when (and (< (- (car pos) 10)
+ (cl-getf area (car corner))
+ (+ (car pos) 10))
+ (< (- (cdr pos) 10)
+ (cl-getf area (cadr corner))
+ (+ (cdr pos) 10)))
+ return corner))
+
+(defun image-crop--content-type (image)
+ ;; Get the MIME type by running "file" over it.
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert image)
+ (call-process-region (point-min) (point-max)
+ "file" t (current-buffer) nil
+ "--mime-type" "-")
+ (cadr (split-string (buffer-string)))))
+
+(defun image-crop--possibly-rotate-buffer (image)
+ (when (imagep image)
+ (let ((content-type (image-crop--content-type (buffer-string))))
+ (when (image-property image :rotation)
+ (cond
+ ;; We can rotate jpegs losslessly by setting the correct
+ ;; orientation.
+ ((and image-crop-exif-rotate
+ (equal content-type "image/jpeg")
+ (executable-find "exiftool"))
+ (call-process-region
+ (point-min) (point-max) "exiftool" t (list (current-buffer) nil) nil
+ (format "-Orientation#=%d"
+ (cl-case (truncate (image-property image :rotation))
+ (0 0)
+ (90 6)
+ (180 3)
+ (270 8)
+ (otherwise 0)))
+ "-o" "-" "-"))
+ ;; Most other image formats have to be reencoded to do
+ ;; rotation.
+ (t
+ (image-crop--process
+ image-crop-rotate-command
+ `((?r . ,(image-property image :rotation))
+ (?f . ,(cadr (split-string content-type "/")))))
+ (when (and (equal content-type "image/jpeg")
+ (executable-find "exiftool"))
+ (call-process-region
+ (point-min) (point-max) "exiftool"
+ t (list (current-buffer) nil) nil
+ "-Orientation#=0"
+ "-o" "-" "-")))))
+ (when (image-property image :width)
+ (image-crop--process
+ image-crop-resize-command
+ `((?w . ,(image-property image :width))
+ (?f . ,(cadr (split-string content-type "/")))))))))
+
+(defun image-crop--insert-image-data (image text)
+ (insert-image
+ (create-image image nil t
+ :max-width (- (frame-pixel-width) 50)
+ :max-height (- (frame-pixel-height) 150))
+ (funcall image-crop-buffer-text-function text image)
+ nil nil t))
+
+(defun image-crop--process (command expansions)
+ "Use `call-process-region' with COMMAND expanded with EXPANSIONS."
+ (apply
+ #'call-process-region (point-min) (point-max)
+ (format-spec (car command) expansions)
+ t (list (current-buffer) nil) nil
+ (mapcar (lambda (elem)
+ (format-spec elem expansions))
+ (cdr command))))
+
+(defun image-crop--default-buffer-text (text _image)
+ (substring-no-properties text))
+
+(provide 'image-crop)
+
+;;; image-crop.el ends here
diff --git a/lisp/image/image-dired-dired.el b/lisp/image/image-dired-dired.el
index ef0323d1665..46adf3f26f6 100644
--- a/lisp/image/image-dired-dired.el
+++ b/lisp/image/image-dired-dired.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2005-2022 Free Software Foundation, Inc.
;; Author: Mathias Dahl <mathias.rem0veth1s.dahl@gmail.com>
+;; Maintainer: Stefan Kangas <stefankangas@gmail.com>
;; Keywords: multimedia
;; This file is part of GNU Emacs.
@@ -22,6 +23,8 @@
;;; Commentary:
+;; See the description of the `image-dired' package.
+
;;; Code:
(require 'image-dired)
@@ -60,14 +63,16 @@ current line. ARG, if non-nil, specifies the files to use instead
of the marked files. If ARG is an integer, use the next ARG (or
previous -ARG, if ARG<0) files."
(interactive "P" dired-mode)
+ (setq image-dired--generate-thumbs-start (current-time))
(dired-map-over-marks
(let ((image-pos (dired-move-to-filename))
(image-file (dired-get-filename nil t))
thumb-file
overlay)
(when (and image-file
- (string-match-p (image-file-name-regexp) image-file))
- (setq thumb-file (image-dired-get-thumbnail-image image-file))
+ (string-match-p (image-dired--file-name-regexp) image-file))
+ (setq thumb-file (create-image
+ (image-dired--get-create-thumbnail-file image-file)))
;; If image is not already added, then add it.
(let ((thumb-ov (cl-loop for ov in (overlays-in (point) (1+ (point)))
if (overlay-get ov 'thumb-file) return ov)))
@@ -79,8 +84,8 @@ previous -ARG, if ARG<0) files."
if (overlay-get ov 'put-image) return ov))
(overlay-put overlay 'image-file image-file)
(overlay-put overlay 'thumb-file thumb-file)))))
- arg ; Show or hide image on ARG next files.
- 'show-progress) ; Update dired display after each image is updated.
+ ;; Show or hide thumbnail on ARG next files.
+ arg)
(add-hook 'dired-after-readin-hook
'image-dired-dired-after-readin-hook nil t))
@@ -162,7 +167,7 @@ but the other way around."
(when found
(if (setq window (image-dired-thumbnail-window))
(set-window-point window (point)))
- (image-dired-update-header-line))))))
+ (image-dired--update-header-line))))))
(defun image-dired-dired-next-line (&optional arg)
"Call `dired-next-line', then track thumbnail.
@@ -197,29 +202,15 @@ With prefix argument, move ARG lines."
(defvar-keymap image-dired-minor-mode-map
:doc "Keymap for `image-dired-minor-mode'."
- ;; Hijack previous and next line movement. Let C-p and C-b be
- ;; though...
- "p" #'image-dired-dired-previous-line
- "n" #'image-dired-dired-next-line
- "<up>" #'image-dired-dired-previous-line
- "<down>" #'image-dired-dired-next-line
-
+ "<remap> <dired-previous-line>" #'image-dired-dired-previous-line
+ "<remap> <dired-next-line>" #'image-dired-dired-next-line
"C-S-n" #'image-dired-next-line-and-display
"C-S-p" #'image-dired-previous-line-and-display
"C-S-m" #'image-dired-mark-and-display-next
-
- "C-t d" #'image-dired-display-thumbs
"<tab>" #'image-dired-jump-thumbnail-buffer
- "C-t i" #'image-dired-dired-display-image
- "C-t x" #'image-dired-dired-display-external
- "C-t a" #'image-dired-display-thumbs-append
- "C-t ." #'image-dired-display-thumb
- "C-t c" #'image-dired-dired-comment-files
- "C-t f" #'image-dired-mark-tagged-files)
-
-(easy-menu-define image-dired-minor-mode-menu image-dired-minor-mode-map
- "Menu for `image-dired-minor-mode'."
- '("Image-dired"
+
+ :menu
+ '("Image-Dired"
["Display thumb for next file" image-dired-next-line-and-display]
["Display thumb for previous file" image-dired-previous-line-and-display]
["Mark and display next" image-dired-mark-and-display-next]
@@ -248,9 +239,39 @@ With prefix argument, move ARG lines."
;;;###autoload
(define-minor-mode image-dired-minor-mode
- "Setup easy-to-use keybindings for the commands to be used in Dired mode.
-Note that n, p and <down> and <up> will be hijacked and bound to
-`image-dired-dired-next-line' and `image-dired-dired-previous-line'."
+ "Setup easy-to-use keybindings for Image-Dired in Dired mode.
+
+This minor mode adds these additional bindings:
+\\<image-dired-minor-mode-map>
+ \\[image-dired-next-line-and-display] Move to next line and display \
+thumbnail image.
+ \\[image-dired-previous-line-and-display] Move to previous line \
+and display thumbnail image.
+ \\[image-dired-mark-and-display-next] Mark current file and display \
+next thumbnail image.
+ \\[image-dired-jump-thumbnail-buffer] Jump to thumbnail buffer.
+
+For reference, these are the default Image-Dired bindings that
+are always available in Dired:
+\\<dired-mode-map>
+ \\[image-dired-display-thumbs] Display thumbnails of all marked files.
+ \\[image-dired-tag-files] Tag marked file(s).
+ \\[image-dired-delete-tag] Remove tag for selected file(s).
+ \\[image-dired-jump-thumbnail-buffer] Jump to thumbnail buffer.
+ \\[image-dired-dired-display-image] Display current image file.
+ \\[image-dired-dired-display-external] Display file at point \
+using an external viewer.
+ \\[image-dired-display-thumbs-append] Append thumbnails to \
+thumbnail buffer.
+ \\[image-dired-display-thumb] Display thumbnails of all marked files.
+ \\[image-dired-dired-comment-files] Add comment to current or \
+marked files in Dired.
+ \\[image-dired-mark-tagged-files] Use REGEXP to mark files with \
+matching tag.
+ \\[image-dired-dired-toggle-marked-thumbs] Toggle thumbnails in \
+front of file names.
+ \\[image-dired-dired-edit-comment-and-tags] Edit comment and tags \
+of marked images."
:keymap image-dired-minor-mode-map)
(declare-function clear-image-cache "image.c" (&optional filter))
@@ -367,17 +388,18 @@ matching tag will be marked in the Dired buffer."
(defun image-dired-dired-display-properties ()
"Display properties for Dired file in the echo area."
(interactive nil dired-mode)
- (let* ((file (dired-get-filename))
- (file-name (file-name-nondirectory file))
+ (let* ((file-name (dired-get-filename))
(dired-buf (buffer-name (current-buffer)))
- (props (mapconcat #'identity (image-dired-list-tags file) ", "))
- (comment (image-dired-get-comment file))
+ (image-count "") ; TODO
+ (props (string-join (image-dired-list-tags file-name) ", "))
+ (comment (image-dired-get-comment file-name))
(message-log-max nil))
(if file-name
(message "%s"
(image-dired-format-properties-string
dired-buf
file-name
+ image-count
props
comment)))))
diff --git a/lisp/image/image-dired-external.el b/lisp/image/image-dired-external.el
index 223d881bcfa..026a84560da 100644
--- a/lisp/image/image-dired-external.el
+++ b/lisp/image/image-dired-external.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2005-2022 Free Software Foundation, Inc.
;; Author: Mathias Dahl <mathias.rem0veth1s.dahl@gmail.com>
+;; Maintainer: Stefan Kangas <stefankangas@gmail.com>
;; Keywords: multimedia
;; This file is part of GNU Emacs.
@@ -22,6 +23,8 @@
;;; Commentary:
+;; See the description of the `image-dired' package.
+
;;; Code:
(require 'dired)
@@ -33,10 +36,9 @@
(declare-function clear-image-cache "image.c" (&optional filter))
(defvar image-dired-dir)
+(defvar image-dired-thumb-size)
(defvar image-dired-main-image-directory)
(defvar image-dired-rotate-original-ask-before-overwrite)
-(defvar image-dired-thumb-height)
-(defvar image-dired-thumb-width)
(defvar image-dired-thumbnail-storage)
(defgroup image-dired-external nil
@@ -59,12 +61,12 @@ Used together with `image-dired-cmd-create-thumbnail-options'."
(if (executable-find "gm") (cons "convert" opts) opts))
"Options of command used to create thumbnail image.
Used with `image-dired-cmd-create-thumbnail-program'.
-Available format specifiers are: %w which is replaced by
-`image-dired-thumb-width', %h which is replaced by `image-dired-thumb-height',
-%f which is replaced by the file name of the original image and %t
-which is replaced by the file name of the thumbnail file."
- :version "29.1"
- :type '(repeat (string :tag "Argument")))
+Available format specifiers are:
+ %s, %w and %h, which are replaced by `image-dired-thumb-size'
+ %f which is replaced by the file name of the original image and
+ %t which is replaced by the file name of the thumbnail file."
+ :type '(repeat (string :tag "Argument"))
+ :version "29.1")
(defcustom image-dired-cmd-pngnq-program
;; Prefer pngquant to pngnq-s9 as it is faster on my machine.
@@ -108,8 +110,8 @@ with the information required by the Thumbnail Managing Standard."
"-text" "b" "Thumb::URI" "file://%f"
"%q" "%t")
"Arguments for `image-dired-cmd-pngcrush-program'.
-Available format specifiers are the same as in
-`image-dired-cmd-create-thumbnail-options', with %q for a
+The available %-format specifiers are the same as in
+`image-dired-cmd-create-thumbnail-options', with \"%q\" for a
temporary file name (typically generated by pnqnq)."
:version "26.1"
:type '(repeat (string :tag "Argument")))
@@ -128,20 +130,20 @@ Available format specifiers are described in
:link '(url-link "man:optipng(1)"))
(defcustom image-dired-cmd-create-standard-thumbnail-options
- (append '("-size" "%wx%h" "%f[0]")
- (unless (or image-dired-cmd-pngcrush-program
- image-dired-cmd-pngnq-program)
- (list
- "-set" "Thumb::MTime" "%m"
- "-set" "Thumb::URI" "file://%f"
- "-set" "Description" "Thumbnail of file://%f"
- "-set" "Software" (emacs-version)))
- '("-thumbnail" "%wx%h>" "png:%t"))
+ (let ((opts (list
+ "-size" "%wx%h" "%f[0]"
+ "-set" "Thumb::MTime" "%m"
+ "-set" "Thumb::URI" "file://%f"
+ "-set" "Description" "Thumbnail of file://%f"
+ "-set" "Software" (emacs-version)
+ "-thumbnail" "%wx%h>" "png:%t")))
+ (if (executable-find "gm") (cons "convert" opts) opts))
"Options for creating thumbnails according to the Thumbnail Managing Standard.
-Available format specifiers are the same as in
-`image-dired-cmd-create-thumbnail-options', with %m for file modification time."
- :version "26.1"
- :type '(repeat (string :tag "Argument")))
+The available %-format specifiers are the same as in
+`image-dired-cmd-create-thumbnail-options', with \"%m\" for file
+modification time."
+ :type '(repeat (string :tag "Argument"))
+ :version "29.1")
(defcustom image-dired-cmd-rotate-original-program "jpegtran"
"Executable used to rotate original image.
@@ -190,17 +192,15 @@ which is replaced by the tag value."
;;; Creating thumbnails
-(defun image-dired-thumb-size (dimension)
- "Return thumb size depending on `image-dired-thumbnail-storage'.
-DIMENSION should be either the symbol `width' or `height'."
- (cond
- ((eq 'standard image-dired-thumbnail-storage) 128)
- ((eq 'standard-large image-dired-thumbnail-storage) 256)
- ((eq 'standard-x-large image-dired-thumbnail-storage) 512)
- ((eq 'standard-xx-large image-dired-thumbnail-storage) 1024)
- (t (cl-ecase dimension
- (width image-dired-thumb-width)
- (height image-dired-thumb-height)))))
+(defun image-dired--thumb-size (&optional _)
+ "Return thumb size depending on `image-dired-thumbnail-storage'."
+ (declare (advertised-calling-convention () "29.1"))
+ (pcase image-dired-thumbnail-storage
+ ('standard 128)
+ ('standard-large 256)
+ ('standard-x-large 512)
+ ('standard-xx-large 1024)
+ (_ image-dired-thumb-size)))
(defvar image-dired--generate-thumbs-start nil
"Time when `display-thumbs' was called.")
@@ -286,21 +286,17 @@ and remove the cached thumbnail files between each trial run.")
"For ORIGINAL-FILE, create thumbnail image named THUMBNAIL-FILE."
(image-dired--check-executable-exists
'image-dired-cmd-create-thumbnail-program)
- (let* ((width (int-to-string (image-dired-thumb-size 'width)))
- (height (int-to-string (image-dired-thumb-size 'height)))
+ (let* ((size (number-to-string (image-dired--thumb-size)))
(modif-time (format-time-string
"%s" (file-attribute-modification-time
(file-attributes original-file))))
(thumbnail-nq8-file (replace-regexp-in-string ".png\\'" "-nq8.png"
thumbnail-file))
- (spec
- (list
- (cons ?w width)
- (cons ?h height)
- (cons ?m modif-time)
- (cons ?f original-file)
- (cons ?q thumbnail-nq8-file)
- (cons ?t thumbnail-file)))
+ (spec `((?s . ,size) (?w . ,size) (?h . ,size)
+ (?m . ,modif-time)
+ (?f . ,original-file)
+ (?q . ,thumbnail-nq8-file)
+ (?t . ,thumbnail-file)))
(thumbnail-dir (file-name-directory thumbnail-file))
process)
(when (not (file-exists-p thumbnail-dir))
@@ -310,15 +306,17 @@ and remove the cached thumbnail files between each trial run.")
;; Thumbnail file creation processes begin here and are marshaled
;; in a queue by `image-dired-create-thumb'.
- (setq process
- (apply #'start-process "image-dired-create-thumbnail" nil
- image-dired-cmd-create-thumbnail-program
- (mapcar
- (lambda (arg) (format-spec arg spec))
- (if (memq image-dired-thumbnail-storage
- image-dired--thumbnail-standard-sizes)
- image-dired-cmd-create-standard-thumbnail-options
- image-dired-cmd-create-thumbnail-options))))
+ (let ((cmd image-dired-cmd-create-thumbnail-program)
+ (args (mapcar
+ (lambda (arg) (format-spec arg spec))
+ (if (memq image-dired-thumbnail-storage
+ image-dired--thumbnail-standard-sizes)
+ image-dired-cmd-create-standard-thumbnail-options
+ image-dired-cmd-create-thumbnail-options))))
+ (image-dired-debug "Running %s %s" cmd (string-join args " "))
+ (setq process
+ (apply #'start-process "image-dired-create-thumbnail" nil
+ cmd args)))
(setf (process-sentinel process)
(lambda (process status)
@@ -326,7 +324,7 @@ and remove the cached thumbnail files between each trial run.")
(cl-decf image-dired-queue-active-jobs)
(image-dired-thumb-queue-run)
(when (= image-dired-queue-active-jobs 0)
- (image-dired-debug-message
+ (image-dired-debug
(format-time-string
"Generated thumbnails in %s.%3N seconds"
(time-subtract nil
@@ -464,6 +462,8 @@ default value at the prompt."
(mapcar (lambda (arg) (format-spec arg spec))
image-dired-cmd-write-exif-data-options))))
+(define-obsolete-function-alias 'image-dired-thumb-size #'image-dired--thumb-size "29.1")
+
(provide 'image-dired-external)
;; Local Variables:
diff --git a/lisp/image/image-dired-tags.el b/lisp/image/image-dired-tags.el
index ee3c63b009f..dfd64732859 100644
--- a/lisp/image/image-dired-tags.el
+++ b/lisp/image/image-dired-tags.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2005-2022 Free Software Foundation, Inc.
;; Author: Mathias Dahl <mathias.rem0veth1s.dahl@gmail.com>
+;; Maintainer: Stefan Kangas <stefankangas@gmail.com>
;; Keywords: multimedia
;; This file is part of GNU Emacs.
@@ -22,6 +23,8 @@
;;; Commentary:
+;; See the description of the `image-dired' package.
+
;;; Code:
(require 'dired)
@@ -32,34 +35,34 @@
(defvar image-dired-dir)
(defvar image-dired-thumbnail-storage)
-(defvar image-dired-db-file)
+(defvar image-dired-tags-db-file)
(defmacro image-dired--with-db-file (&rest body)
- "Run BODY in a temp buffer containing `image-dired-db-file'.
+ "Run BODY in a temp buffer containing `image-dired-tags-db-file'.
Return the last form in BODY."
(declare (indent 0) (debug t))
`(with-temp-buffer
- (if (file-exists-p image-dired-db-file)
- (insert-file-contents image-dired-db-file))
+ (if (file-exists-p image-dired-tags-db-file)
+ (insert-file-contents image-dired-tags-db-file))
,@body))
(defun image-dired-sane-db-file ()
- "Check if `image-dired-db-file' exists.
+ "Check if `image-dired-tags-db-file' exists.
If not, try to create it (including any parent directories).
Signal error if there are problems creating it."
- (or (file-exists-p image-dired-db-file)
+ (or (file-exists-p image-dired-tags-db-file)
(let (dir buf)
(unless (file-directory-p (setq dir (file-name-directory
- image-dired-db-file)))
+ image-dired-tags-db-file)))
(with-file-modes #o700
(make-directory dir t)))
(with-current-buffer (setq buf (create-file-buffer
- image-dired-db-file))
+ image-dired-tags-db-file))
(with-file-modes #o600
- (write-file image-dired-db-file)))
+ (write-file image-dired-tags-db-file)))
(kill-buffer buf)
- (file-exists-p image-dired-db-file))
- (error "Could not create %s" image-dired-db-file)))
+ (file-exists-p image-dired-tags-db-file))
+ (error "Could not create %s" image-dired-tags-db-file)))
(defvar image-dired-tag-history nil "Variable holding the tag history.")
@@ -71,7 +74,7 @@ FILE-TAGS is an alist in the following form:
(image-dired-sane-db-file)
(let (end file tag)
(image-dired--with-db-file
- (setq buffer-file-name image-dired-db-file)
+ (setq buffer-file-name image-dired-tags-db-file)
(dolist (elt file-tags)
(setq file (car elt)
tag (cdr elt))
@@ -91,7 +94,7 @@ FILE-TAGS is an alist in the following form:
"For all FILES, remove TAG from the image database."
(image-dired-sane-db-file)
(image-dired--with-db-file
- (setq buffer-file-name image-dired-db-file)
+ (setq buffer-file-name image-dired-tags-db-file)
(let (end)
(unless (listp files)
(if (stringp files)
@@ -106,8 +109,8 @@ FILE-TAGS is an alist in the following form:
(when (search-forward-regexp
(format "\\(;%s\\)\\($\\|;\\)" tag) end t)
(delete-region (match-beginning 1) (match-end 1))
- ;; Check if file should still be in the database. If
- ;; it has no tags or comments, it will be removed.
+ ;; Check if file should still be in the database.
+ ;; If it has no tags or comments, it will be removed.
(end-of-line)
(setq end (point))
(beginning-of-line)
@@ -191,7 +194,7 @@ FILE-COMMENTS is an alist on the following form:
(image-dired-sane-db-file)
(let (end comment-beg-pos comment-end-pos file comment)
(image-dired--with-db-file
- (setq buffer-file-name image-dired-db-file)
+ (setq buffer-file-name image-dired-tags-db-file)
(dolist (elt file-comments)
(setq file (car elt)
comment (cdr elt))
@@ -290,11 +293,14 @@ easy-to-use form."
(remove-overlays)
;; Some help for the user.
(widget-insert
- "\nEdit comments and tags for each image. Separate multiple tags
-with a comma. Move forward between fields using TAB or RET.
-Move to the previous field using backtab (S-TAB). Save by
-activating the Save button at the bottom of the form or cancel
-the operation by activating the Cancel button.\n\n")
+ (substitute-command-keys
+ "\\<widget-field-keymap>
+Edit comments and tags for each image. Separate multiple tags
+with a comma. Move forward between fields using \\[widget-forward] \
+or \\[widget-field-activate].
+Move to the previous field using \\[widget-backward]. Save by
+activating the \"Save\" button at the bottom of the form or
+cancel the operation by activating the \"Cancel\" button.\n\n"))
;; Here comes all images and a comment and tag field for each
;; image.
(let (thumb-file img comment-widget tag-widget)
diff --git a/lisp/image/image-dired-util.el b/lisp/image/image-dired-util.el
index 6eb5fa18ce7..bc7a3552620 100644
--- a/lisp/image/image-dired-util.el
+++ b/lisp/image/image-dired-util.el
@@ -3,6 +3,7 @@
;; Copyright (C) 2005-2022 Free Software Foundation, Inc.
;; Author: Mathias Dahl <mathias.rem0veth1s.dahl@gmail.com>
+;; Maintainer: Stefan Kangas <stefankangas@gmail.com>
;; This file is part of GNU Emacs.
@@ -21,6 +22,8 @@
;;; Commentary:
+;; See the description of the `image-dired' package.
+
;;; Code:
(require 'xdg)
@@ -37,7 +40,7 @@
(defvar image-dired-debug nil
"Non-nil means enable debug messages.")
-(defun image-dired-debug-message (&rest args)
+(defun image-dired-debug (&rest args)
"Display debug message ARGS when `image-dired-debug' is non-nil."
(when image-dired-debug
(apply #'message args)))
@@ -45,8 +48,9 @@
(defun image-dired-dir ()
"Return the current thumbnail directory (from variable `image-dired-dir').
Create the thumbnail directory if it does not exist."
- (let ((image-dired-dir (file-name-as-directory
- (expand-file-name image-dired-dir))))
+ (let ((image-dired-dir
+ (file-name-as-directory
+ (expand-file-name image-dired-dir))))
(unless (file-directory-p image-dired-dir)
(with-file-modes #o700
(make-directory image-dired-dir t))
@@ -66,32 +70,29 @@ file name of the thumbnail will vary:
of the image file's directory name will be added to the
filename.
See also `image-dired-thumbnail-storage'."
- (cond ((memq image-dired-thumbnail-storage
- image-dired--thumbnail-standard-sizes)
- (let ((thumbdir (cl-case image-dired-thumbnail-storage
- (standard "thumbnails/normal")
- (standard-large "thumbnails/large")
- (standard-x-large "thumbnails/x-large")
- (standard-xx-large "thumbnails/xx-large"))))
- (expand-file-name
- ;; MD5 is mandated by the Thumbnail Managing Standard.
- (concat (md5 (concat "file://" (expand-file-name file))) ".png")
- (expand-file-name thumbdir (xdg-cache-home)))))
- ((eq 'use-image-dired-dir image-dired-thumbnail-storage)
- (let* ((f (expand-file-name file))
- (hash
- (md5 (file-name-as-directory (file-name-directory f)))))
- (format "%s%s%s.thumb.%s"
- (file-name-as-directory (expand-file-name (image-dired-dir)))
- (file-name-base f)
- (if hash (concat "_" hash) "")
- (file-name-extension f))))
- ((eq 'per-directory image-dired-thumbnail-storage)
- (let ((f (expand-file-name file)))
- (format "%s.image-dired/%s.thumb.%s"
- (file-name-directory f)
- (file-name-base f)
- (file-name-extension f))))))
+ (let ((file (expand-file-name file)))
+ (cond ((memq image-dired-thumbnail-storage
+ image-dired--thumbnail-standard-sizes)
+ (let ((thumbdir (cl-case image-dired-thumbnail-storage
+ (standard "thumbnails/normal")
+ (standard-large "thumbnails/large")
+ (standard-x-large "thumbnails/x-large")
+ (standard-xx-large "thumbnails/xx-large"))))
+ (expand-file-name
+ ;; MD5 is mandated by the Thumbnail Managing Standard.
+ (concat (md5 (concat "file://" file)) ".png")
+ (expand-file-name thumbdir (xdg-cache-home)))))
+ ((or (eq 'image-dired image-dired-thumbnail-storage)
+ ;; Maintained for backwards compatibility:
+ (eq 'use-image-dired-dir image-dired-thumbnail-storage))
+ (expand-file-name (format "%s.jpg" (sha1 file))
+ (image-dired-dir)))
+ ((eq 'per-directory image-dired-thumbnail-storage)
+ (expand-file-name (format "%s.thumb.jpg"
+ (file-name-nondirectory file))
+ (expand-file-name
+ ".image-dired"
+ (file-name-directory file)))))))
(defvar image-dired-thumbnail-buffer "*image-dired*"
"Image-Dired's thumbnail buffer.")
@@ -112,6 +113,21 @@ See also `image-dired-thumbnail-storage'."
"Get associated Dired buffer at point."
(get-text-property (point) 'associated-dired-buffer))
+(defmacro image-dired--with-dired-buffer (&rest body)
+ "Run BODY in associated Dired buffer.
+Should be used by commands in `image-dired-thumbnail-mode'."
+ (declare (indent defun) (debug t))
+ (let ((file (make-symbol "file"))
+ (dired-buf (make-symbol "dired-buf")))
+ `(let ((,file (image-dired-original-file-name))
+ (,dired-buf (image-dired-associated-dired-buffer)))
+ (unless ,file
+ (error "No image at point"))
+ (unless (and ,dired-buf (buffer-live-p ,dired-buf))
+ (error "Cannot find associated Dired buffer for image: %s" ,file))
+ (with-current-buffer ,dired-buf
+ ,@body))))
+
(defun image-dired-get-buffer-window (buf)
"Return window where buffer BUF is."
(get-window-with-predicate
@@ -121,6 +137,10 @@ See also `image-dired-thumbnail-storage'."
(defun image-dired-display-window ()
"Return window where `image-dired-display-image-buffer' is visible."
+ ;; This is obsolete as it is currently unused. Once the window
+ ;; handling gets a rethink, there may or may not be a need to
+ ;; un-obsolete it again.
+ (declare (obsolete nil "29.1"))
(get-window-with-predicate
(lambda (window)
(equal (buffer-name (window-buffer window)) image-dired-display-image-buffer))
@@ -135,6 +155,10 @@ See also `image-dired-thumbnail-storage'."
(defun image-dired-associated-dired-buffer-window ()
"Return window where associated Dired buffer is visible."
+ ;; This is obsolete as it is currently unused. Once the window
+ ;; handling gets a rethink, there may or may not be a need to
+ ;; un-obsolete it again.
+ (declare (obsolete nil "29.1"))
(let (buf)
(if (image-dired-image-at-point-p)
(progn
diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el
index a22edee2ec5..d4fd3c62db1 100644
--- a/lisp/image/image-dired.el
+++ b/lisp/image/image-dired.el
@@ -3,7 +3,8 @@
;; Copyright (C) 2005-2022 Free Software Foundation, Inc.
;; Author: Mathias Dahl <mathias.rem0veth1s.dahl@gmail.com>
-;; Version: 0.4.11
+;; Maintainer: Stefan Kangas <stefankangas@gmail.com>
+;; Version: 0.5
;; Keywords: multimedia
;; This file is part of GNU Emacs.
@@ -46,7 +47,7 @@
;; browsing the thumbnail buffer was slow too. image-dired.el will not
;; create thumbnails until they are needed and the browsing is done
;; quickly and easily in Dired. I copied a great deal of ideas and
-;; code from there though... :)
+;; code from there though... :)
;;
;; `image-dired' stores the thumbnail files in `image-dired-dir'
;; using the file name format ORIGNAME.thumb.ORIGEXT. For example
@@ -55,7 +56,6 @@
;;
;; file-name-non-directory;comment:comment-text;tag1;tag2;tag3;...;tagN
;;
-;;
;; PREREQUISITES
;; =============
;;
@@ -98,7 +98,7 @@
;; option `image-dired-thumbnail-storage'.
;;
;; * WARNING: The "database" format used might be changed so keep a
-;; backup of `image-dired-db-file' when testing new versions.
+;; backup of `image-dired-tags-db-file' when testing new versions.
;;
;; TODO
;; ====
@@ -109,8 +109,6 @@
;; * From thumbs.el: Add an option for clean-up/max-size functionality
;; for thumbnail directory.
;;
-;; * From thumbs.el: Add setroot function.
-;;
;; * Add `image-dired-display-thumbs-ring' and functions to cycle that. Find out
;; which is best, saving old batch just before inserting new, or
;; saving the current batch in the ring when inserting it. Adding
@@ -158,40 +156,50 @@
(defcustom image-dired-dir (locate-user-emacs-file "image-dired/")
"Directory where thumbnail images are stored.
-The value of this option will be ignored if Image-Dired is
-customized to use the Thumbnail Managing Standard; they will be
-saved in \"$XDG_CACHE_HOME/thumbnails/\" instead. See
+The value of this option is ignored if Image-Dired is customized
+to use the Thumbnail Managing Standard; they will be saved in
+\"$XDG_CACHE_HOME/thumbnails/\" instead. See
`image-dired-thumbnail-storage'."
:type 'directory)
-(defcustom image-dired-thumbnail-storage 'use-image-dired-dir
+(defcustom image-dired-thumbnail-storage 'image-dired
"How `image-dired' stores thumbnail files.
-There are two ways that Image-Dired can store and generate
-thumbnails. If you set this variable to one of the two following
-values, they will be stored in the JPEG format:
+There are three ways that Image-Dired can store and generate
+thumbnails:
+
+ 1. According to the \"Thumbnail Managing Standard\", which allows
+ sharing of thumbnails across different programs. Thumbnails
+ will be stored in \"$XDG_CACHE_HOME/thumbnails/\"
+
+ Set this user option to one of the following values:
+
+ - `standard' means use thumbnails sized 128x128.
+ - `standard-large' means use thumbnails sized 256x256.
+ - `standard-x-large' means use thumbnails sized 512x512.
+ - `standard-xx-large' means use thumbnails sized 1024x1024.
+
+ 2. In the Image-Dired specific directory indicated by
+ `image-dired-dir'.
+
+ Set this user option to `image-dired' to use it (or
+ `use-image-dired-dir', which means the same thing for
+ backwards-compatibility reasons).
-- `use-image-dired-dir' means that the thumbnails are stored in a
- central directory.
+ 3. In a subdirectory \".image-dired\" in the same directory
+ where the image files are.
-- `per-directory' means that each thumbnail is stored in a
- subdirectory called \".image-dired\" in the same directory
- where the image file is.
+ Set this user option to `per-directory' to use it.
-It can also use the \"Thumbnail Managing Standard\", which allows
-sharing of thumbnails across different programs. Thumbnails will
-be stored in \"$XDG_CACHE_HOME/thumbnails/\" instead of in
-`image-dired-dir'. Thumbnails are saved in the PNG format, and
-can be one of the following sizes:
+To change the default size of thumbnails with (2) and (3) above,
+customize `image-dired-thumb-size'.
-- `standard' means use thumbnails sized 128x128.
-- `standard-large' means use thumbnails sized 256x256.
-- `standard-x-large' means use thumbnails sized 512x512.
-- `standard-xx-large' means use thumbnails sized 1024x1024.
+With Thumbnail Managing Standard, save thumbnails in the PNG
+format, as mandated by that standard, and otherwise as JPEG.
For more information on the Thumbnail Managing Standard, see:
https://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html"
:type '(choice :tag "How to store thumbnail files"
- (const :tag "Use image-dired-dir" use-image-dired-dir)
+ (const :tag "Use image-dired-dir" image-dired)
(const :tag "Thumbnail Managing Standard (normal 128x128)"
standard)
(const :tag "Thumbnail Managing Standard (large 256x256)"
@@ -202,11 +210,13 @@ https://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html
standard-xx-large)
(const :tag "Per-directory" per-directory))
:version "29.1")
+;;;###autoload(put 'image-dired-thumbnail-storage 'safe-local-variable (lambda (x) (eq x 'per-directory)))
-(defcustom image-dired-db-file
+(define-obsolete-variable-alias 'image-dired-db-file
+ 'image-dired-tags-db-file "29.1")
+(defcustom image-dired-tags-db-file
(expand-file-name ".image-dired_db" image-dired-dir)
"Database file where file names and their associated tags are stored."
- :group 'image-dired
:type 'file)
(defcustom image-dired-rotate-original-ask-before-overwrite t
@@ -216,37 +226,30 @@ original file with `image-dired-temp-rotate-image-file'."
:type 'boolean)
(defcustom image-dired-thumb-size
- (cond
- ((eq 'standard image-dired-thumbnail-storage) 128)
- ((eq 'standard-large image-dired-thumbnail-storage) 256)
- ((eq 'standard-x-large image-dired-thumbnail-storage) 512)
- ((eq 'standard-xx-large image-dired-thumbnail-storage) 1024)
- (t 100))
- "Size of thumbnails, in pixels.
-This is the default size for both `image-dired-thumb-width'
-and `image-dired-thumb-height'.
-
-The value of this option will be ignored if Image-Dired is
-customized to use the Thumbnail Managing Standard; the standard
-sizes will be used instead. See `image-dired-thumbnail-storage'."
- :type 'integer)
-
-(defcustom image-dired-thumb-width image-dired-thumb-size
- "Width of thumbnails, in pixels."
- :type 'integer)
-
-(defcustom image-dired-thumb-height image-dired-thumb-size
- "Height of thumbnails, in pixels."
- :type 'integer)
+ ;; This is ignored when using the Thumbnail Managing Standard, but
+ ;; this provides a better default (e.g., when 'image-dired-thumbnail-storage'
+ ;; is `image-dired' in a directory local variables).
+ (pcase image-dired-thumbnail-storage
+ ('standard 128)
+ ('standard-large 256)
+ ('standard-x-large 512)
+ ('standard-xx-large 1024)
+ (_ 128))
+ "Default size of thumbnails in pixels.
+The value of this option is ignored if Image-Dired is customized
+to use the Thumbnail Managing Standard; the standard sizes will
+be used instead. See `image-dired-thumbnail-storage'."
+ :type 'natnum
+ :version "29.1")
(defcustom image-dired-thumb-relief 2
"Size of button-like border around thumbnails."
- :type 'integer)
+ :type 'natnum)
(defcustom image-dired-thumb-margin 2
"Size of the margin around thumbnails.
This is where you see the cursor."
- :type 'integer)
+ :type 'natnum)
(defcustom image-dired-thumb-visible-marks t
"Make marks and flags visible in thumbnail buffer.
@@ -256,22 +259,6 @@ deletion."
:type 'boolean
:version "28.1")
-(defface image-dired-thumb-mark
- '((((class color) (min-colors 16)) :background "DarkOrange")
- (((class color)) :foreground "yellow"))
- "Face for marked images in thumbnail buffer."
- :version "29.1")
-
-(defface image-dired-thumb-flagged
- '((((class color) (min-colors 88) (background light)) :background "Red3")
- (((class color) (min-colors 88) (background dark)) :background "Pink")
- (((class color) (min-colors 16) (background light)) :background "Red3")
- (((class color) (min-colors 16) (background dark)) :background "Pink")
- (((class color) (min-colors 8)) :background "red")
- (t :inverse-video t))
- "Face for images flagged for deletion in thumbnail buffer."
- :version "29.1")
-
(defcustom image-dired-line-up-method 'dynamic
"Default method for line-up of thumbnails in thumbnail buffer.
Used by `image-dired-display-thumbs' and other functions that needs
@@ -287,7 +274,7 @@ and No line-up means that no automatic line-up will be done."
(defcustom image-dired-thumbs-per-row 3
"Number of thumbnails to display per row in thumb buffer."
- :type 'integer)
+ :type 'natnum)
(defcustom image-dired-track-movement t
"The current state of the tracking and mirroring.
@@ -295,24 +282,38 @@ For more information, see the documentation for
`image-dired-toggle-movement-tracking'."
:type 'boolean)
-(defcustom image-dired-display-properties-format "%b: %f (%t): %c"
+(defcustom image-dired-display-properties-format "%n %d/%f %s %t %c"
"Display format for thumbnail properties.
-%b is replaced with associated Dired buffer name, %f with file
-name (without path) of original image file, %t with the list of
-tags and %c with the comment."
- :type 'string)
+This is used for the header line in the Image-Dired buffer.
+
+The following %-specs are replaced by `format-spec' before
+displaying:
+
+ \"%f\" The file name (without a directory) of the
+ original image file.
+ \"%n\" The number of this image out of the total (e.g. 1/10).
+ \"%b\" The associated Dired buffer name.
+ \"%d\" The name of the directory that the file is in.
+ \"%s\" The image file size.
+ \"%t\" The list of tags (from the Image-Dired database).
+ \"%c\" The comment (from the Image-Dired database)."
+ :type 'string
+ :safe #'stringp
+ :version "29.1")
(defcustom image-dired-external-viewer
;; TODO: Use mailcap, dired-guess-shell-alist-default,
;; dired-view-command-alist.
- (cond ((executable-find "display"))
- ((executable-find "xli"))
+ (cond ((executable-find "display") "display")
+ ((executable-find "feh") "feh")
+ ((executable-find "gm") "gm display")
+ ((executable-find "xli") "xli")
((executable-find "qiv") "qiv -t")
- ((executable-find "feh") "feh"))
+ ((executable-find "xloadimage") "xloadimage"))
"Name of external viewer.
Including parameters. Used when displaying original image from
`image-dired-thumbnail-mode'."
- :version "28.1"
+ :version "29.1"
:type '(choice string
(const :tag "Not Set" nil)))
@@ -346,8 +347,59 @@ This affects the following commands:
:version "29.1")
+;;; Faces
+
+;;;; Header line
+
+(defface image-dired-thumb-header-file-name
+ '((default :weight bold))
+ "Face for the file name in the header line of the thumbnail buffer."
+ :version "29.1")
+
+(defface image-dired-thumb-header-directory-name
+ '((default :inherit header-line))
+ "Face for the directory name in the header line of the thumbnail buffer."
+ :version "29.1")
+
+(defface image-dired-thumb-header-file-size
+ '((((class color) (min-colors 88)) :foreground "cadet blue")
+ (((class color) (min-colors 16)) :foreground "black")
+ (default :inherit header-line))
+ "Face for the file size in the header line of the thumbnail buffer."
+ :version "29.1")
+
+(defface image-dired-thumb-header-image-count
+ '((default :inherit header-line))
+ "Face for the image count in the header line of the thumbnail buffer."
+ :version "29.1")
+
+;;;; Thumbnail buffer
+
+(defface image-dired-thumb-mark
+ '((((class color) (min-colors 16)) :background "DarkOrange")
+ (((class color)) :foreground "yellow")
+ (default :inherit header-line))
+ "Face for marked images in thumbnail buffer."
+ :version "29.1")
+
+(defface image-dired-thumb-flagged
+ '((((class color) (min-colors 88) (background light)) :background "Red3")
+ (((class color) (min-colors 88) (background dark)) :background "Pink")
+ (((class color) (min-colors 16) (background light)) :background "Red3")
+ (((class color) (min-colors 16) (background dark)) :background "Pink")
+ (((class color) (min-colors 8)) :background "red")
+ (t :inverse-video t))
+ "Face for images flagged for deletion in thumbnail buffer."
+ :version "29.1")
+
+
;;; Util functions
+(defun image-dired--file-name-regexp ()
+ (let ((image-file-name-extensions
+ (append '("pdf") image-file-name-extensions)))
+ (image-file-name-regexp)))
+
(defun image-dired-insert-image (file type relief margin)
"Insert image FILE of image TYPE, using RELIEF and MARGIN, at point."
(let ((i `(image :type ,type
@@ -356,23 +408,27 @@ This affects the following commands:
:margin ,margin)))
(insert-image i)))
-(defun image-dired-get-thumbnail-image (file)
+(defun image-dired--get-create-thumbnail-file (file)
"Return the image descriptor for a thumbnail of image file FILE."
- (unless (string-match-p (image-file-name-regexp) file)
+ (unless (string-match-p (image-dired--file-name-regexp) file)
(error "%s is not a valid image file" file))
(let* ((thumb-file (image-dired-thumb-name file))
(thumb-attr (file-attributes thumb-file)))
- (when (or (not thumb-attr)
- (time-less-p (file-attribute-modification-time thumb-attr)
- (file-attribute-modification-time
- (file-attributes file))))
- (image-dired-create-thumb file thumb-file))
- (create-image thumb-file)))
+ (if (or (not thumb-attr)
+ (time-less-p (file-attribute-modification-time thumb-attr)
+ (file-attribute-modification-time
+ (file-attributes file))))
+ (image-dired-create-thumb file thumb-file)
+ (image-dired-debug "Found thumb for %s: %s"
+ (file-name-nondirectory file)
+ (file-name-nondirectory thumb-file)))
+ thumb-file))
(defun image-dired-insert-thumbnail ( file original-file-name
- associated-dired-buffer)
+ associated-dired-buffer image-number)
"Insert thumbnail image FILE.
-Add text properties ORIGINAL-FILE-NAME and ASSOCIATED-DIRED-BUFFER."
+Add text properties ORIGINAL-FILE-NAME, ASSOCIATED-DIRED-BUFFER
+and IMAGE-NUMBER."
(let (beg end)
(setq beg (point))
(image-dired-insert-image
@@ -392,8 +448,11 @@ Add text properties ORIGINAL-FILE-NAME and ASSOCIATED-DIRED-BUFFER."
(add-text-properties
beg end
(list 'image-dired-thumbnail t
+ ;; Disable `image-map' on thumbnails.
+ 'keymap nil
'original-file-name original-file-name
'associated-dired-buffer associated-dired-buffer
+ 'image-number image-number
'tags (image-dired-list-tags original-file-name)
'mouse-face 'highlight
'comment (image-dired-get-comment original-file-name)))))
@@ -401,7 +460,8 @@ Add text properties ORIGINAL-FILE-NAME and ASSOCIATED-DIRED-BUFFER."
(defmacro image-dired--with-marked (&rest body)
"Eval BODY with point on each marked thumbnail.
If no marked file could be found, execute BODY on the current
-thumbnail."
+thumbnail. It's expected that a thumbnail is always followed
+by exactly one space or one newline character."
`(with-current-buffer image-dired-thumbnail-buffer
(let (found)
(save-mark-and-excursion
@@ -410,7 +470,7 @@ thumbnail."
(when (image-dired-thumb-file-marked-p)
(setq found t)
,@body)
- (forward-char)))
+ (forward-char 2)))
(unless found
,@body))))
@@ -426,6 +486,9 @@ thumbnail."
(defvar image-dired-saved-window-configuration nil
"Saved window configuration.")
+
+;;; Starting Image-Dired
+
;;;###autoload
(defun image-dired-dired-with-window-configuration (dir &optional arg)
"Open directory DIR and create a default window configuration.
@@ -483,6 +546,8 @@ Restore any changes to the window configuration made by calling
(t
(image-dired-line-up-dynamic))))
+(defvar-local image-dired--number-of-thumbnails nil)
+
;;;###autoload
(defun image-dired-display-thumbs (&optional arg append do-not-pop)
"Display thumbnails of all marked files, in `image-dired-thumbnail-buffer'.
@@ -507,7 +572,7 @@ thumbnail buffer to be selected."
(interactive "P" nil dired-mode)
(setq image-dired--generate-thumbs-start (current-time))
(let ((buf (image-dired-create-thumbnail-buffer))
- thumb-name files dired-buf)
+ files dired-buf)
(if arg
(setq files (list (dired-get-filename)))
(setq files (dired-get-marked-files)))
@@ -515,13 +580,15 @@ thumbnail buffer to be selected."
(with-current-buffer buf
(let ((inhibit-read-only t))
(if (not append)
- (erase-buffer)
+ (progn
+ (setq image-dired--number-of-thumbnails 0)
+ (erase-buffer))
(goto-char (point-max)))
- (dolist (curr-file files)
- (setq thumb-name (image-dired-thumb-name curr-file))
- (when (not (file-exists-p thumb-name))
- (image-dired-create-thumb curr-file thumb-name))
- (image-dired-insert-thumbnail thumb-name curr-file dired-buf)))
+ (dolist (file files)
+ (let ((thumb (image-dired--get-create-thumbnail-file file)))
+ (image-dired-insert-thumbnail
+ thumb file dired-buf
+ (cl-incf image-dired--number-of-thumbnails)))))
(if do-not-pop
(display-buffer buf)
(pop-to-buffer buf))
@@ -530,16 +597,16 @@ thumbnail buffer to be selected."
;;;###autoload
(defun image-dired-show-all-from-dir (dir)
"Make a thumbnail buffer for all images in DIR and display it.
-Any file matching `image-file-name-regexp' is considered an image
-file.
+Any file matching `image-dired--file-name-regexp' is considered an
+image file.
If the number of image files in DIR exceeds
`image-dired-show-all-from-dir-max-files', ask for confirmation
before creating the thumbnail buffer. If that variable is nil,
never ask for confirmation."
- (interactive "DImage-Dired: ")
+ (interactive "DShow thumbnails for directory: ")
(dired dir)
- (dired-mark-files-regexp (image-file-name-regexp))
+ (dired-mark-files-regexp (image-dired--file-name-regexp))
(let ((files (dired-get-marked-files nil nil nil t)))
(cond ((and (null (cdr files)))
(message "No image files in directory"))
@@ -551,30 +618,30 @@ never ask for confirmation."
"Directory contains more than %d image files. Proceed?"
image-dired-show-all-from-dir-max-files))))
(image-dired-display-thumbs)
+ (let ((inhibit-message t))
+ (dired-unmark-all-marks))
(pop-to-buffer image-dired-thumbnail-buffer)
(setq default-directory dir)
- (image-dired-unmark-all-marks))
+ (image-dired--update-header-line))
(t (message "Image-Dired canceled")))))
;;;###autoload
(defalias 'image-dired 'image-dired-show-all-from-dir)
-;;; Thumbnail mode (cont.)
+;;; Movement tracking
(defun image-dired-track-original-file ()
"Track the original file in the associated Dired buffer.
-See documentation for `image-dired-toggle-movement-tracking'.
-Interactive use only useful if `image-dired-track-movement' is nil."
- (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode)
- (let* ((dired-buf (image-dired-associated-dired-buffer))
- (file-name (image-dired-original-file-name))
- (window (image-dired-get-buffer-window dired-buf)))
- (and (buffer-live-p dired-buf) file-name
- (with-current-buffer dired-buf
- (if (not (dired-goto-file file-name))
- (message "Could not track file")
- (if window (set-window-point window (point))))))))
+See `image-dired-toggle-movement-tracking'. Interactive use is
+only useful if `image-dired-track-movement' is nil."
+ (interactive nil image-dired-thumbnail-mode image-dired-image-mode)
+ (let ((file-name (image-dired-original-file-name)))
+ (image-dired--with-dired-buffer
+ (if (not (dired-goto-file file-name))
+ (message "Could not find image in Dired buffer for tracking")
+ (when-let (window (image-dired-get-buffer-window (current-buffer)))
+ (set-window-point window (point)))))))
(defun image-dired-toggle-movement-tracking ()
"Turn on and off `image-dired-track-movement'.
@@ -582,21 +649,15 @@ Tracking of the movements between thumbnail and Dired buffer so that
they are \"mirrored\" in the dired buffer. When this is on, moving
around in the thumbnail or dired buffer will find the matching
position in the other buffer."
- (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode)
+ (interactive nil image-dired-thumbnail-mode image-dired-image-mode)
(setq image-dired-track-movement (not image-dired-track-movement))
(message "Movement tracking %s" (if image-dired-track-movement "on" "off")))
-(defun image-dired--display-thumb-properties-fun ()
- (let ((old-buf (current-buffer))
- (old-point (point)))
- (lambda ()
- (when (and (equal (current-buffer) old-buf)
- (= (point) old-point))
- (ignore-errors
- (image-dired-update-header-line))))))
+
+;;; Navigation
(defun image-dired-forward-image (&optional arg wrap-around)
- "Move to next image and display properties.
+ "Move to next image in the thumbnail buffer.
Optional prefix ARG says how many images to move; the default is
one image. Negative means move backwards.
On reaching end or beginning of buffer, stop and show a message.
@@ -615,108 +676,130 @@ point is on the last image, move to the last one and vice versa."
(forward-char (if (> arg 0) 1 -1)))
(setq pos (point))
(image-dired-image-at-point-p)))
- (progn (goto-char pos)
- (image-dired-update-header-line))
+ (goto-char pos)
(if wrap-around
- (progn (goto-char (if (> arg 0)
- (point-min)
- ;; There are two spaces after the last image.
- (- (point-max) 2)))
- (image-dired-update-header-line))
- (message "At %s image" (if (> arg 0) "last" "first"))
- (run-at-time 1 nil (image-dired--display-thumb-properties-fun))))))
+ (goto-char (if (> arg 0)
+ (point-min)
+ ;; There are two spaces after the last image.
+ (- (point-max) 2)))
+ (message "At %s image" (if (> arg 0) "last" "first"))))))
+ (image-dired--update-header-line)
(when image-dired-track-movement
(image-dired-track-original-file)))
(defun image-dired-backward-image (&optional arg)
- "Move to previous image and display properties.
+ "Move to previous image in the thumbnail buffer.
Optional prefix ARG says how many images to move; the default is
one image. Negative means move forward.
On reaching end or beginning of buffer, stop and show a message."
(interactive "p" image-dired-thumbnail-mode)
(image-dired-forward-image (- (or arg 1))))
+(defun image-dired--movement-ensure-point-pos (&optional reverse)
+ "Ensure point is on an image."
+ (while (and (not (image-at-point-p))
+ (not (if reverse (bobp) (eobp))))
+ (forward-char (if reverse -1 1))))
+
+(defmacro image-dired--movement-command (to &optional reverse)
+ `(progn
+ (goto-char ,to)
+ (image-dired--movement-ensure-point-pos ,reverse)
+ (when image-dired-track-movement
+ (image-dired-track-original-file))
+ (image-dired--update-header-line)))
+
+(defmacro image-dired--movement-command-line (&optional reverse)
+ `(image-dired--movement-command
+ (let ((goal-column (current-column)))
+ (forward-line ,(if reverse -1 1))
+ (move-to-column goal-column)
+ (point))
+ ,reverse))
+
(defun image-dired-next-line ()
- "Move to next line and display properties."
+ "Move to next line in the thumbnail buffer."
(interactive nil image-dired-thumbnail-mode)
- (let ((goal-column (current-column)))
- (forward-line 1)
- (move-to-column goal-column))
- ;; If we end up in an empty spot, back up to the next thumbnail.
- (if (not (image-dired-image-at-point-p))
- (image-dired-backward-image))
- (if image-dired-track-movement
- (image-dired-track-original-file))
- (image-dired-update-header-line))
+ (image-dired--movement-command-line))
(defun image-dired-previous-line ()
- "Move to previous line and display properties."
+ "Move to previous line in the thumbnail buffer."
(interactive nil image-dired-thumbnail-mode)
- (let ((goal-column (current-column)))
- (forward-line -1)
- (move-to-column goal-column))
- ;; If we end up in an empty spot, back up to the next
- ;; thumbnail. This should only happen if the user deleted a
- ;; thumbnail and did not refresh, so it is not very common. But we
- ;; can handle it in a good manner, so why not?
- (if (not (image-dired-image-at-point-p))
- (image-dired-backward-image))
- (if image-dired-track-movement
- (image-dired-track-original-file))
- (image-dired-update-header-line))
+ (image-dired--movement-command-line 'reverse))
(defun image-dired-beginning-of-buffer ()
- "Move to the first image in the buffer and display properties."
+ "Move to the first image in the thumbnail buffer."
(interactive nil image-dired-thumbnail-mode)
- (goto-char (point-min))
- (while (and (not (image-at-point-p))
- (not (eobp)))
- (forward-char 1))
- (when image-dired-track-movement
- (image-dired-track-original-file))
- (image-dired-update-header-line))
+ (image-dired--movement-command (point-min)))
(defun image-dired-end-of-buffer ()
- "Move to the last image in the buffer and display properties."
+ "Move to the last image in the thumbnail buffer."
(interactive nil image-dired-thumbnail-mode)
- (goto-char (point-max))
- (while (and (not (image-at-point-p))
- (not (bobp)))
- (forward-char -1))
- (when image-dired-track-movement
- (image-dired-track-original-file))
- (image-dired-update-header-line))
+ (image-dired--movement-command (point-max) 'reverse))
+
+(defun image-dired-move-beginning-of-line ()
+ "Move to the beginning of current line in thumbnail buffer."
+ (interactive nil image-dired-thumbnail-mode)
+ (image-dired--movement-command (pos-bol)))
+
+(defun image-dired-move-end-of-line ()
+ "Move to the end of current line in thumbnail buffer."
+ (interactive nil image-dired-thumbnail-mode)
+ (image-dired--movement-command (pos-eol) 'reverse))
+
+
+;;; Header line
-(defun image-dired-format-properties-string (buf file props comment)
+(defun image-dired-format-properties-string (buf file image-count props comment)
"Format display properties.
-BUF is the associated Dired buffer, FILE is the original image file
-name, PROPS is a stringified list of tags and COMMENT is the image file's
+BUF is the associated Dired buffer, FILE is the original image
+file name, IMAGE-COUNT is a string like \"N/M\" where N is the
+number of this image and M is the total number of images, PROPS
+is a stringified list of tags, and COMMENT is the image file's
comment."
(format-spec
image-dired-display-properties-format
- (list
- (cons ?b (or buf ""))
- (cons ?f file)
- (cons ?t (or props ""))
- (cons ?c (or comment "")))))
-
-(defun image-dired-update-header-line ()
+ `((?b . ,(or buf ""))
+ (?d . ,(propertize
+ (file-name-nondirectory
+ (directory-file-name
+ (file-name-directory file)))
+ 'face 'image-dired-thumb-header-directory-name))
+ (?f . ,(propertize (file-name-nondirectory file)
+ 'face 'image-dired-thumb-header-file-name))
+ (?n . ,(propertize image-count
+ 'face 'image-dired-thumb-header-image-count))
+ (?s . ,(propertize (if (file-exists-p file)
+ (file-size-human-readable
+ (file-attribute-size
+ (file-attributes file)))
+ "<File missing>")
+ 'face 'image-dired-thumb-header-file-size))
+ (?t . ,(or props ""))
+ (?c . ,(or comment "")))))
+
+(defun image-dired--update-header-line ()
"Update image information in the header line."
- (when (and (not (eobp))
- (memq major-mode '(image-dired-thumbnail-mode
- image-dired-display-image-mode)))
- (let ((file-name (file-name-nondirectory (image-dired-original-file-name)))
+ (when (derived-mode-p 'image-dired-thumbnail-mode)
+ (let ((file-name (image-dired-original-file-name))
(dired-buf (buffer-name (image-dired-associated-dired-buffer)))
- (props (mapconcat #'identity (get-text-property (point) 'tags) ", "))
+ (image-count (format "%s/%s"
+ (get-text-property (point) 'image-number)
+ image-dired--number-of-thumbnails))
+ (props (string-join (get-text-property (point) 'tags) ", "))
(comment (get-text-property (point) 'comment))
(message-log-max nil))
- (if file-name
- (setq header-line-format
- (image-dired-format-properties-string
- dired-buf
- file-name
- props
- comment))))))
+ (when file-name
+ (setq header-line-format
+ (image-dired-format-properties-string
+ dired-buf
+ file-name
+ image-count
+ props
+ comment))))))
+
+
+;;; Marking and flagging
(defun image-dired-dired-file-marked-p (&optional marker)
"In Dired, return t if file on current line is marked.
@@ -732,6 +815,16 @@ for. The default is to look for `dired-marker-char'."
"In Dired, return t if file on current line is flagged for deletion."
(image-dired-dired-file-marked-p dired-del-marker))
+(defmacro image-dired--on-file-in-dired-buffer (&rest body)
+ "Run BODY with point on file at point in Dired buffer.
+Should be called from commands in `image-dired-thumbnail-mode'."
+ (declare (indent defun) (debug t))
+ `(if-let ((file-name (image-dired-original-file-name)))
+ (image-dired--with-dired-buffer
+ (when (dired-goto-file file-name)
+ ,@body))
+ (message "No image with correct properties at point")))
+
(defmacro image-dired--with-thumbnail-buffer (&rest body)
(declare (indent defun) (debug t))
`(if-let ((buf (get-buffer image-dired-thumbnail-buffer)))
@@ -742,104 +835,77 @@ for. The default is to look for `dired-marker-char'."
,@body))
(user-error "No such buffer: %s" image-dired-thumbnail-buffer)))
-(defmacro image-dired--on-file-in-dired-buffer (&rest body)
- "Run BODY with point on file at point in Dired buffer.
-Should be called from commands in `image-dired-thumbnail-mode'."
- (declare (indent defun) (debug t))
- `(let ((file-name (image-dired-original-file-name))
- (dired-buf (image-dired-associated-dired-buffer)))
- (if (not (and dired-buf file-name))
- (message "No image, or image with correct properties, at point")
- (with-current-buffer dired-buf
- (when (dired-goto-file file-name)
- ,@body
- (image-dired-thumb-update-marks))))))
-
-(defmacro image-dired--do-mark-command (maybe-next &rest body)
- "Helper macro for the mark, unmark and flag commands.
-Run BODY in Dired buffer.
-If optional argument MAYBE-NEXT is non-nil, show next image
-according to `image-dired-marking-shows-next'."
+(defmacro image-dired--do-mark-command (maybe-next update-mark &rest body)
+ "Run BODY in Dired buffer.
+Helper macro for the mark, unmark and flag commands.
+
+If MAYBE-NEXT is non-nil, show next image according to
+`image-dired-marking-shows-next'.
+
+If UPDATE-MARK is non-nil, also update the mark in the thumbnail
+buffer with `image-dired--thumb-update-mark-at-point'."
(declare (indent defun) (debug t))
`(image-dired--with-thumbnail-buffer
(image-dired--on-file-in-dired-buffer
,@body)
+ ,(when update-mark
+ '(image-dired--thumb-update-mark-at-point))
,(when maybe-next
'(if image-dired-marking-shows-next
- (image-dired-display-next-thumbnail-original)
+ (image-dired-display-next)
(image-dired-forward-image)))))
(defun image-dired-mark-thumb-original-file ()
"Mark original image file in associated Dired buffer."
- (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode)
- (image-dired--do-mark-command t
+ (interactive nil image-dired-thumbnail-mode image-dired-image-mode)
+ (image-dired--do-mark-command t t
(dired-mark 1)))
(defun image-dired-unmark-thumb-original-file ()
"Unmark original image file in associated Dired buffer."
- (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode)
- (image-dired--do-mark-command t
+ (interactive nil image-dired-thumbnail-mode image-dired-image-mode)
+ (image-dired--do-mark-command t t
(dired-unmark 1)))
(defun image-dired-flag-thumb-original-file ()
"Flag original image file for deletion in associated Dired buffer."
- (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode)
- (image-dired--do-mark-command t
+ (interactive nil image-dired-thumbnail-mode image-dired-image-mode)
+ (image-dired--do-mark-command t t
(dired-flag-file-deletion 1)))
-(defun image-dired-toggle-mark-thumb-original-file ()
- "Toggle mark on original image file in associated Dired buffer."
- (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode)
- (image-dired--do-mark-command nil
- (if (image-dired-dired-file-marked-p)
- (dired-unmark 1)
- (dired-mark 1))))
-
(defun image-dired-unmark-all-marks ()
"Remove all marks from all files in associated Dired buffer.
Also update the marks in the thumbnail buffer."
- (interactive nil image-dired-thumbnail-mode image-dired-display-image-mode)
- (image-dired--do-mark-command nil
+ (interactive nil image-dired-thumbnail-mode image-dired-image-mode)
+ (image-dired--do-mark-command nil t
(dired-unmark-all-marks))
(image-dired--with-thumbnail-buffer
- (image-dired-thumb-update-marks)))
+ (image-dired--thumb-update-marks)))
(defun image-dired-jump-original-dired-buffer ()
"Jump to the Dired buffer associated with the current image file.
You probably want to use this together with
`image-dired-track-original-file'."
(interactive nil image-dired-thumbnail-mode)
- (let ((buf (image-dired-associated-dired-buffer))
- window frame)
- (setq window (image-dired-get-buffer-window buf))
- (if window
+ (image-dired--with-dired-buffer
+ (if-let ((window (image-dired-get-buffer-window (current-buffer))))
(progn
- (if (not (equal (selected-frame) (setq frame (window-frame window))))
- (select-frame-set-input-focus frame))
+ (if (not (equal (selected-frame) (window-frame window)))
+ (select-frame-set-input-focus (window-frame window)))
(select-window window))
- (message "Associated dired buffer not visible"))))
+ (message "Associated Dired buffer not visible"))))
+
+
+;;; Major modes
(defvar-keymap image-dired-thumbnail-mode-map
:doc "Keymap for `image-dired-thumbnail-mode'."
- "<right>" #'image-dired-forward-image
- "<left>" #'image-dired-backward-image
- "<up>" #'image-dired-previous-line
- "<down>" #'image-dired-next-line
- "C-f" #'image-dired-forward-image
- "C-b" #'image-dired-backward-image
- "C-p" #'image-dired-previous-line
- "C-n" #'image-dired-next-line
-
- "<" #'image-dired-beginning-of-buffer
- ">" #'image-dired-end-of-buffer
- "M-<" #'image-dired-beginning-of-buffer
- "M->" #'image-dired-end-of-buffer
-
"d" #'image-dired-flag-thumb-original-file
"<delete>" #'image-dired-flag-thumb-original-file
"m" #'image-dired-mark-thumb-original-file
"u" #'image-dired-unmark-thumb-original-file
"U" #'image-dired-unmark-all-marks
+ "x" #'image-dired-do-flagged-delete
"." #'image-dired-track-original-file
"<tab>" #'image-dired-jump-original-dired-buffer
@@ -850,7 +916,7 @@ You probably want to use this together with
"t t" #'image-dired-tag-thumbnail
"t r" #'image-dired-tag-thumbnail-remove
- "RET" #'image-dired-display-thumbnail-original-image
+ "RET" #'image-dired-display-this
"C-<return>" #'image-dired-thumbnail-display-external
"L" #'image-dired-rotate-original-left
@@ -859,29 +925,37 @@ You probably want to use this together with
"D" #'image-dired-thumbnail-set-image-description
"S" #'image-dired-slideshow-start
"C-d" #'image-dired-delete-char
- "SPC" #'image-dired-display-next-thumbnail-original
- "DEL" #'image-dired-display-previous-thumbnail-original
+ "SPC" #'image-dired-display-next
+ "DEL" #'image-dired-display-previous
"c" #'image-dired-comment-thumbnail
+ "w" #'image-dired-copy-filename-as-kill
+ "W" #'image-dired-wallpaper-set
;; Mouse
"<mouse-2>" #'image-dired-mouse-display-image
+ "<double-mouse-1>" #'image-dired-mouse-display-image
"<mouse-1>" #'image-dired-mouse-select-thumbnail
"<mouse-3>" #'image-dired-mouse-select-thumbnail
"<down-mouse-1>" #'image-dired-mouse-select-thumbnail
"<down-mouse-2>" #'image-dired-mouse-select-thumbnail
"<down-mouse-3>" #'image-dired-mouse-select-thumbnail
- ;; Seems I must first set C-down-mouse-1 to undefined, or else it
- ;; will trigger the buffer menu. If I try to instead bind
- ;; C-down-mouse-1 to `image-dired-mouse-toggle-mark', I get a message
- ;; about C-mouse-1 not being defined afterwards. Annoying, but I
- ;; probably do not completely understand mouse events.
- "C-<down-mouse-1>" #'undefined
- "C-<mouse-1>" #'image-dired-mouse-toggle-mark)
-
-(easy-menu-define image-dired-thumbnail-mode-menu image-dired-thumbnail-mode-map
- "Menu for `image-dired-thumbnail-mode'."
+ "C-<down-mouse-1>" #'ignore ; Don't open the buffer menu.
+ "C-<mouse-1>" #'image-dired-mouse-toggle-mark
+
+ "<remap> <forward-char>" #'image-dired-forward-image
+ "<remap> <backward-char>" #'image-dired-backward-image
+ "<remap> <next-line>" #'image-dired-next-line
+ "<remap> <previous-line>" #'image-dired-previous-line
+ "<remap> <left-char>" #'image-dired-backward-image
+ "<remap> <right-char>" #'image-dired-forward-image
+ "<remap> <beginning-of-buffer>" #'image-dired-beginning-of-buffer
+ "<remap> <end-of-buffer>" #'image-dired-end-of-buffer
+ "<remap> <move-beginning-of-line>" #'image-dired-move-beginning-of-line
+ "<remap> <move-end-of-line>" #'image-dired-move-end-of-line
+
+ :menu
'("Image-Dired"
- ["Display image" image-dired-display-thumbnail-original-image]
+ ["Display image" image-dired-display-this]
["Display in external viewer" image-dired-thumbnail-display-external]
["Jump to Dired buffer" image-dired-jump-original-dired-buffer]
"---"
@@ -889,7 +963,7 @@ You probably want to use this together with
["Unmark image" image-dired-unmark-thumb-original-file]
["Unmark all images" image-dired-unmark-all-marks]
["Flag for deletion" image-dired-flag-thumb-original-file]
- ["Delete marked images" image-dired-delete-marked]
+ ["Delete flagged images" image-dired-do-flagged-delete]
"---"
["Rotate original right" image-dired-rotate-original-right]
["Rotate original left" image-dired-rotate-original-left]
@@ -910,25 +984,12 @@ You probably want to use this together with
["Refresh thumb" image-dired-refresh-thumb])
["Quit" quit-window]))
-(defvar-keymap image-dired-display-image-mode-map
- :doc "Keymap for `image-dired-display-image-mode'."
- "S" #'image-dired-slideshow-start
- "SPC" #'image-dired-display-next-thumbnail-original
- "DEL" #'image-dired-display-previous-thumbnail-original
- "n" #'image-dired-display-next-thumbnail-original
- "p" #'image-dired-display-previous-thumbnail-original
- "m" #'image-dired-mark-thumb-original-file
- "d" #'image-dired-flag-thumb-original-file
- "u" #'image-dired-unmark-thumb-original-file
- "U" #'image-dired-unmark-all-marks
- ;; Disable keybindings from `image-mode-map' that doesn't make sense here.
- "o" nil) ; image-save
-
(define-derived-mode image-dired-thumbnail-mode
special-mode "image-dired-thumbnail"
"Browse and manipulate thumbnail images using Dired.
Use `image-dired-minor-mode' to get a nice setup."
:interactive nil
+ :group 'image-dired
(buffer-disable-undo)
(add-hook 'file-name-at-point-functions 'image-dired-file-name-at-point nil t)
(setq-local window-resize-pixelwise t)
@@ -937,13 +998,32 @@ Use `image-dired-minor-mode' to get a nice setup."
(setq-local line-spacing (frame-char-width)))
-;;; Display image mode
+;;; image-dired-image-mode
+
+(define-obsolete-variable-alias 'image-dired-display-image-mode-map
+ 'image-dired-image-mode-map "29.1")
+(defvar-keymap image-dired-image-mode-map
+ :doc "Keymap for `image-dired-image-mode'."
+ "S" #'image-dired-slideshow-start
+ "SPC" #'image-dired-display-next
+ "DEL" #'image-dired-display-previous
+ "n" #'image-dired-display-next
+ "p" #'image-dired-display-previous
+ "m" #'image-dired-mark-thumb-original-file
+ "d" #'image-dired-flag-thumb-original-file
+ "u" #'image-dired-unmark-thumb-original-file
+ "U" #'image-dired-unmark-all-marks
+ ;; Disable keybindings from `image-mode-map' that doesn't make sense here.
+ "o" nil) ; image-save
-(define-derived-mode image-dired-display-image-mode
+(define-derived-mode image-dired-image-mode
image-mode "image-dired-image-display"
"Mode for displaying and manipulating original image.
Resized or in full-size."
:interactive nil
+ :group 'image-dired
+ (setq-local column-number-mode nil)
+ (setq-local line-number-mode nil)
(add-hook 'file-name-at-point-functions #'image-dired-file-name-at-point nil t))
@@ -960,59 +1040,92 @@ This is used by `image-dired-slideshow-start'."
(defvar image-dired--slideshow-timer nil
"Slideshow timer.")
-(defvar image-dired--slideshow-initial nil)
+(defvar image-dired--slideshow-current-delay image-dired-slideshow-delay)
-(defun image-dired-slideshow-step ()
- "Step to next image in a slideshow."
+(defun image-dired--slideshow-step ()
+ "Step to the next image in a slideshow."
(if-let ((buf (get-buffer image-dired-thumbnail-buffer)))
(with-current-buffer buf
- (image-dired-display-next-thumbnail-original))
- (image-dired-slideshow-stop)))
+ (image-dired-display-next))
+ (image-dired--slideshow-stop)))
+
+(defun image-dired--slideshow-start-timer ()
+ (image-dired--slideshow-stop-timer)
+ (setq image-dired--slideshow-timer
+ (run-with-timer image-dired--slideshow-current-delay
+ image-dired--slideshow-current-delay
+ 'image-dired--slideshow-step)))
+
+(defun image-dired--slideshow-stop-timer ()
+ (when image-dired--slideshow-timer
+ (cancel-timer image-dired--slideshow-timer)
+ (setq image-dired--slideshow-timer nil)))
(defun image-dired-slideshow-start (&optional arg)
- "Start a slideshow, waiting `image-dired-slideshow-delay' between images.
+ "Start a slideshow, waiting `image-dired-slideshow-delay' seconds between images.
With prefix argument ARG, wait that many seconds before going to
the next image.
With a negative prefix argument, prompt user for the delay."
- (interactive "P" image-dired-thumbnail-mode image-dired-display-image-mode)
- (let ((delay (if (not arg)
- image-dired-slideshow-delay
- (if (> arg 0)
- arg
- (string-to-number
- (let ((delay (number-to-string image-dired-slideshow-delay)))
- (read-string
- (format-prompt "Delay, in seconds. Decimals are accepted" delay))
- delay))))))
- (setq image-dired--slideshow-timer
- (run-with-timer
- 0 delay
- 'image-dired-slideshow-step))
- (add-hook 'post-command-hook 'image-dired-slideshow-stop)
- (setq image-dired--slideshow-initial t)
- (message "Running slideshow; use any command to stop")))
-
-(defun image-dired-slideshow-stop ()
- "Cancel slideshow."
- ;; Make sure we don't immediately stop after
- ;; `image-dired-slideshow-start'.
- (unless image-dired--slideshow-initial
- (remove-hook 'post-command-hook 'image-dired-slideshow-stop)
- (cancel-timer image-dired--slideshow-timer))
- (setq image-dired--slideshow-initial nil))
+ (interactive "P" image-dired-thumbnail-mode image-dired-image-mode)
+ (let ((delay
+ (cond ((not arg)
+ image-dired-slideshow-delay)
+ ((> arg 0)
+ arg)
+ ((<= arg 0)
+ (string-to-number
+ (let ((delay (number-to-string image-dired-slideshow-delay)))
+ (read-string
+ (format-prompt "Delay, in seconds. Decimals are accepted"
+ delay))
+ delay))))))
+ (image-dired-display-this)
+ (setq image-dired--slideshow-current-delay delay)
+ (add-hook 'post-command-hook 'image-dired--slideshow-stop)))
+
+(defun image-dired--slideshow-show-message (&optional suffix)
+ "Helper function for `image-dired--slideshow-stop'."
+ (message (substitute-command-keys
+ (format
+ (concat
+ "\\[image-dired-display-next] next, "
+ "\\[image-dired-display-previous] previous, "
+ "\\[image-dired-display-this] pause/unpause, "
+ "any other command to stop%s")
+ (or suffix "")))))
+
+(defun image-dired--slideshow-stop ()
+ "Cancel the currently active slideshow."
+ (cond
+ ((memq this-command
+ '( image-dired-slideshow-start
+ image-dired-display-next
+ image-dired-display-previous))
+ (image-dired--slideshow-start-timer)
+ (image-dired--slideshow-show-message))
+ ((eq this-command 'image-dired-display-this)
+ (let ((pause image-dired--slideshow-timer))
+ (if pause
+ (image-dired--slideshow-stop-timer)
+ (image-dired--slideshow-start-timer))
+ (image-dired--slideshow-show-message (and pause " [PAUSED]"))))
+ (t
+ (image-dired--slideshow-stop-timer)
+ (remove-hook 'post-command-hook 'image-dired--slideshow-stop))))
-;;; Thumbnail mode (cont. 3)
+;;; Thumbnail layout and display
(defun image-dired-delete-char ()
"Remove current thumbnail from thumbnail buffer and line up."
(interactive nil image-dired-thumbnail-mode)
(let ((inhibit-read-only t))
- (delete-char 1)
- (when (= (following-char) ?\s)
- (delete-char 1))))
+ (delete-char 1))
+ (let ((pos (point)))
+ (image-dired--line-up-with-method)
+ (goto-char pos)))
(defun image-dired-line-up ()
"Line up thumbnails according to `image-dired-thumbs-per-row'.
@@ -1034,7 +1147,7 @@ See also `image-dired-line-up-dynamic'."
(thumb-width-chars
(ceiling (/ (+ (* 2 image-dired-thumb-relief)
(* 2 image-dired-thumb-margin)
- (image-dired-thumb-size 'width))
+ (image-dired--thumb-size))
(float (frame-char-width))))))
(while (not (eobp))
(forward-char)
@@ -1061,7 +1174,7 @@ Calculate how many thumbnails fit."
(/ width
(+ (* 2 image-dired-thumb-relief)
(* 2 image-dired-thumb-margin)
- (image-dired-thumb-size 'width)
+ (image-dired--thumb-size)
char-width))))
(image-dired-line-up)))
@@ -1075,6 +1188,9 @@ Ask user how many thumbnails should be displayed per row."
(message "Number must be greater than 0")
(image-dired-line-up))))
+
+;;; Display image from thumbnail buffer
+
(defun image-dired-thumbnail-display-external ()
"Display original image for thumbnail at point using external viewer."
(interactive nil image-dired-thumbnail-mode)
@@ -1083,14 +1199,14 @@ Ask user how many thumbnails should be displayed per row."
(message "No thumbnail at point")
(if (not file)
(message "No original file name found")
- (start-process "image-dired-thumb-external" nil
- image-dired-external-viewer file)))))
+ (apply #'start-process "image-dired-thumb-external" nil
+ (append (string-split image-dired-external-viewer " ")
+ (list file)))))))
(defun image-dired-display-image (file &optional _ignored)
- "Display image FILE in image buffer.
-Use this when you want to display the image, in a new window.
-The window will use `image-dired-display-image-mode' which is
-based on `image-mode'."
+ "Display image FILE in the image buffer window.
+If it is an image, the window will use `image-dired-image-mode'
+which is based on `image-mode'."
(declare (advertised-calling-convention (file) "29.1"))
(setq file (expand-file-name file))
(when (not (file-exists-p file))
@@ -1102,22 +1218,43 @@ based on `image-mode'."
(when-let ((buf (find-file-noselect file nil t)))
(pop-to-buffer buf)
(rename-buffer image-dired-display-image-buffer)
- (image-dired-display-image-mode)
+ (if (string-match (image-file-name-regexp) file)
+ (image-dired-image-mode)
+ ;; Support visiting PDF files.
+ (normal-mode))
(select-window cur-win))))
-(defun image-dired-display-thumbnail-original-image (&optional arg)
+(defun image-dired-display-this (&optional arg)
"Display current thumbnail's original image in display buffer.
See documentation for `image-dired-display-image' for more information.
With prefix argument ARG, display image in its original size."
(interactive "P" image-dired-thumbnail-mode)
+ (unless (string-equal major-mode "image-dired-thumbnail-mode")
+ (user-error "Not in `image-dired-thumbnail-mode'"))
(let ((file (image-dired-original-file-name)))
- (if (not (string-equal major-mode "image-dired-thumbnail-mode"))
- (message "Not in image-dired-thumbnail-mode")
- (if (not (image-dired-image-at-point-p))
- (message "No thumbnail at point")
- (if (not file)
- (message "No original file name found")
- (image-dired-display-image file arg))))))
+ (cond ((not (image-dired-image-at-point-p))
+ (message "No thumbnail at point"))
+ ((not file)
+ (message "No original file name found"))
+ (t
+ (image-dired-display-image file arg)))))
+
+(defun image-dired-display-next (&optional arg)
+ "Move to the next image in the thumbnail buffer and display it.
+With prefix ARG, move that many thumbnails."
+ (interactive "p" image-dired-thumbnail-mode image-dired-image-mode)
+ (image-dired--with-thumbnail-buffer
+ (image-dired-forward-image arg t)
+ (image-dired-display-this)))
+
+(defun image-dired-display-previous (arg)
+ "Move to the previous image in the thumbnail buffer and display it.
+With prefix ARG, move that many thumbnails."
+ (interactive "p" image-dired-thumbnail-mode image-dired-image-mode)
+ (image-dired-display-next (- arg)))
+
+
+;;; Misc commands
(defun image-dired-rotate-original-left ()
"Rotate original image left (counter clockwise) 90 degrees.
@@ -1139,31 +1276,27 @@ overwritten. This confirmation can be turned off using
(image-dired--with-marked
(image-dired-rotate-original "90")))
-(defun image-dired-display-next-thumbnail-original (&optional arg)
- "Move to the next image in the thumbnail buffer and display it.
-With prefix ARG, move that many thumbnails."
- (interactive "p" image-dired-thumbnail-mode image-dired-display-image-mode)
- (image-dired--with-thumbnail-buffer
- (image-dired-forward-image arg t)
- (image-dired-display-thumbnail-original-image)))
-
-(defun image-dired-display-previous-thumbnail-original (arg)
- "Move to the previous image in the thumbnail buffer and display it.
-With prefix ARG, move that many thumbnails."
- (interactive "p" image-dired-thumbnail-mode image-dired-display-image-mode)
- (image-dired-display-next-thumbnail-original (- arg)))
-
-
-;;; Image Comments
+(defun image-dired-wallpaper-set (file)
+ "Set the wallpaper to FILE in a graphical environment."
+ (interactive (list (image-dired-original-file-name))
+ image-dired-thumbnail-mode)
+ (wallpaper-set file))
(defun image-dired-comment-thumbnail ()
"Add comment to current thumbnail in thumbnail buffer."
- (interactive nil image-dired-comment-thumbnail image-dired-display-image-mode)
+ (interactive nil image-dired-thumbnail-mode)
(let* ((file (image-dired-original-file-name))
(comment (image-dired-read-comment file)))
(image-dired-write-comments (list (cons file comment)))
(image-dired-update-property 'comment comment))
- (image-dired-update-header-line))
+ (image-dired--update-header-line))
+
+(defun image-dired-copy-filename-as-kill (&optional arg)
+ "Copy names of marked (or next ARG) files into the kill ring.
+This works as `dired-copy-filename-as-kill' (which see)."
+ (interactive "P" image-dired-thumbnail-mode)
+ (image-dired--with-dired-buffer
+ (dired-copy-filename-as-kill arg)))
;;; Mouse support
@@ -1194,7 +1327,7 @@ non-nil."
(image-dired-backward-image))
(if image-dired-track-movement
(image-dired-track-original-file))
- (image-dired-update-header-line))
+ (image-dired--update-header-line))
@@ -1204,51 +1337,62 @@ non-nil."
"Check if file is marked in associated Dired buffer.
If optional argument FLAGGED is non-nil, check if file is flagged
for deletion instead."
- (let ((file-name (image-dired-original-file-name))
- (dired-buf (image-dired-associated-dired-buffer)))
- (when (and dired-buf file-name)
- (with-current-buffer dired-buf
- (save-excursion
- (when (dired-goto-file file-name)
- (if flagged
- (image-dired-dired-file-flagged-p)
- (image-dired-dired-file-marked-p))))))))
+ (let ((file-name (image-dired-original-file-name)))
+ (image-dired--with-dired-buffer
+ (save-excursion
+ (when (dired-goto-file file-name)
+ (if flagged
+ (image-dired-dired-file-flagged-p)
+ (image-dired-dired-file-marked-p)))))))
(defun image-dired-thumb-file-flagged-p ()
"Check if file is flagged for deletion in associated Dired buffer."
(image-dired-thumb-file-marked-p t))
-(defun image-dired-delete-marked ()
- "Delete current or marked thumbnails and associated images."
+(defun image-dired-do-flagged-delete ()
+ "Delete flagged thumbnails and associated images."
(interactive nil image-dired-thumbnail-mode)
(unless (derived-mode-p 'image-dired-thumbnail-mode)
(user-error "Not in `image-dired-thumbnail-mode'"))
- (image-dired--with-marked
- (image-dired-delete-char)
- (unless (bobp)
- (backward-char)))
- (image-dired--line-up-with-method)
- (with-current-buffer (image-dired-associated-dired-buffer)
- (dired-do-delete)))
-
-(defun image-dired-thumb-update-marks ()
- "Update the marks in the thumbnail buffer."
+ (image-dired--with-dired-buffer
+ (dired-do-flagged-delete))
+ (let (deletions)
+ (save-excursion
+ (let ((inhibit-read-only t))
+ (goto-char (point-min))
+ (while (not (eobp))
+ (let ((file-name (image-dired-original-file-name)))
+ (if (image-dired--with-dired-buffer (dired-goto-file file-name))
+ (forward-char 2)
+ (delete-char 1)
+ (forward-char)
+ (setq deletions t))))))
+ (if deletions
+ (image-dired--line-up-with-method))))
+
+(defun image-dired--thumb-update-mark-at-point ()
+ (with-silent-modifications
+ (cond ((image-dired-thumb-file-marked-p)
+ (add-face-text-property (point) (1+ (point))
+ 'image-dired-thumb-mark))
+ ((image-dired-thumb-file-flagged-p)
+ (add-face-text-property (point) (1+ (point))
+ 'image-dired-thumb-flagged))
+ (t (remove-text-properties (point) (1+ (point))
+ '(face image-dired-thumb-mark))))))
+
+(defun image-dired--thumb-update-marks ()
+ "Update the marks in the thumbnail buffer.
+It's expected, that a thumbnail is always followed
+by exactly one space or one newline character."
(when image-dired-thumb-visible-marks
(with-current-buffer image-dired-thumbnail-buffer
(save-mark-and-excursion
(goto-char (point-min))
(let ((inhibit-read-only t))
(while (not (eobp))
- (with-silent-modifications
- (cond ((image-dired-thumb-file-marked-p)
- (add-face-text-property (point) (1+ (point))
- 'image-dired-thumb-mark))
- ((image-dired-thumb-file-flagged-p)
- (add-face-text-property (point) (1+ (point))
- 'image-dired-thumb-flagged))
- (t (remove-text-properties (point) (1+ (point))
- '(face image-dired-thumb-mark)))))
- (forward-char)))))))
+ (image-dired--thumb-update-mark-at-point)
+ (forward-char 2)))))))
(defun image-dired-mouse-toggle-mark-1 ()
"Toggle Dired mark for current thumbnail.
@@ -1256,7 +1400,10 @@ Track this in associated Dired buffer if
`image-dired-track-movement' is non-nil."
(when image-dired-track-movement
(image-dired-track-original-file))
- (image-dired-toggle-mark-thumb-original-file))
+ (image-dired--do-mark-command nil nil
+ (if (image-dired-dired-file-marked-p)
+ (dired-unmark 1)
+ (dired-mark 1))))
(defun image-dired-mouse-toggle-mark (event)
"Use mouse EVENT to toggle Dired mark for thumbnail.
@@ -1275,7 +1422,7 @@ Track this in associated Dired buffer if
(mouse-set-point event)
(goto-char (posn-point (event-end event)))
(image-dired-mouse-toggle-mark-1))
- (image-dired-thumb-update-marks))
+ (image-dired--thumb-update-marks))
;;; bookmark.el support
@@ -1309,6 +1456,7 @@ Track this in associated Dired buffer if
(goto-char (point-min))))
(put 'image-dired-bookmark-jump 'bookmark-handler-type "Image-Dired")
+
;;; Obsolete
@@ -1319,6 +1467,18 @@ Track this in associated Dired buffer if
(define-obsolete-function-alias 'image-dired-setup-dired-keybindings
#'image-dired-minor-mode "26.1")
+(make-obsolete-variable 'image-dired-thumb-width
+ 'image-dired-thumb-size "29.1")
+(defcustom image-dired-thumb-width image-dired-thumb-size
+ "Width of thumbnails, in pixels."
+ :type 'natnum)
+
+(make-obsolete-variable 'image-dired-thumb-height
+ 'image-dired-thumb-size "29.1")
+(defcustom image-dired-thumb-height image-dired-thumb-size
+ "Height of thumbnails, in pixels."
+ :type 'natnum)
+
(defcustom image-dired-temp-image-file
(expand-file-name ".image-dired_temp" image-dired-dir)
"Name of temporary image file used by various commands."
@@ -1367,6 +1527,15 @@ completely fit)."
(make-obsolete-variable 'image-dired-display-window-height-correction
"no longer used." "29.1")
+(defun image-dired-toggle-mark-thumb-original-file ()
+ "Toggle mark on original image file in associated Dired buffer."
+ (declare (obsolete nil "29.1"))
+ (interactive nil image-dired-thumbnail-mode image-dired-image-mode)
+ (image-dired--do-mark-command nil t
+ (if (image-dired-dired-file-marked-p)
+ (dired-unmark 1)
+ (dired-mark 1))))
+
(defun image-dired-display-window-width (window)
"Return width, in pixels, of WINDOW."
(declare (obsolete nil "29.1"))
@@ -1499,18 +1668,18 @@ Dired."
(dired-unmark 1)
(dired-mark 1)))
((eq command 'flag) (dired-flag-file-deletion 1)))
- (image-dired-thumb-update-marks))))))
+ (image-dired--thumb-update-marks))))))
(defun image-dired-display-current-image-full ()
"Display current image in full size."
- (declare (obsolete image-transform-original "29.1"))
+ (declare (obsolete image-transform-reset-to-original "29.1"))
(interactive nil image-dired-thumbnail-mode)
(let ((file (image-dired-original-file-name)))
(if file
(progn
(image-dired-display-image file)
(with-current-buffer image-dired-display-image-buffer
- (image-transform-original)))
+ (image-transform-reset-to-original)))
(error "No original file name at point"))))
(defun image-dired-display-current-image-sized ()
@@ -1539,9 +1708,6 @@ Dired."
(cons (list tag file) (cdr image-dired-tag-file-list))))
(setq image-dired-tag-file-list (list (list tag file))))))
-(define-obsolete-function-alias 'image-dired-display-thumb-properties
- #'image-dired-update-header-line "29.1")
-
(defvar image-dired-slideshow-count 0
"Keeping track on number of images in slideshow.")
(make-obsolete-variable 'image-dired-slideshow-count "no longer used." "29.1")
@@ -1781,8 +1947,11 @@ when using per-directory thumbnail file storage"))
(insert " </body>\n")
(insert "</html>"))))
+(define-obsolete-function-alias 'image-dired-slideshow-step #'image-dired--slideshow-step "29.1")
+(define-obsolete-function-alias 'image-dired-slideshow-stop #'image-dired--slideshow-stop "29.1")
(define-obsolete-function-alias 'image-dired-create-display-image-buffer
#'ignore "29.1")
+;; These can't use the #' quote as they point to obsolete names.
(define-obsolete-function-alias 'image-dired-create-gallery-lists
'image-dired--create-gallery-lists "29.1")
(define-obsolete-function-alias 'image-dired-add-to-file-comment-list
@@ -1791,6 +1960,22 @@ when using per-directory thumbnail file storage"))
'image-dired--add-to-tag-file-lists "29.1")
(define-obsolete-function-alias 'image-dired-hidden-p
'image-dired--hidden-p "29.1")
+(define-obsolete-function-alias 'image-dired-thumb-update-marks
+ #'image-dired--thumb-update-marks "29.1")
+(define-obsolete-function-alias 'image-dired-get-thumbnail-image
+ #'image-dired--get-create-thumbnail-file "29.1")
+(define-obsolete-function-alias 'image-dired-display-thumb-properties
+ #'image-dired--update-header-line "29.1")
+(define-obsolete-function-alias 'image-dired-delete-marked
+ #'image-dired-do-flagged-delete "29.1")
+(define-obsolete-function-alias 'image-dired-display-image-mode
+ #'image-dired-image-mode "29.1")
+(define-obsolete-function-alias 'image-dired-display-thumbnail-original-image
+ #'image-dired-display-this "29.1")
+(define-obsolete-function-alias 'image-dired-display-next-thumbnail-original
+ #'image-dired-display-next "29.1")
+(define-obsolete-function-alias 'image-dired-display-previous-thumbnail-original
+ #'image-dired-display-previous "29.1")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;; TEST-SECTION ;;;;;;;;;;;
@@ -1811,7 +1996,7 @@ when using per-directory thumbnail file storage"))
;; `(,(file-attribute-access-time fattribs)
;; ,(file-attribute-size fattribs) ,f)))
;; (directory-files (image-dired-dir) t ".+\\.thumb\\..+$"))
-;; ;; Sort function. Compare time between two files.
+;; ;; Sort function. Compare time between two files.
;; (lambda (l1 l2)
;; (time-less-p (car l1) (car l2)))))
;; (dirsize (apply '+ (mapcar (lambda (x) (cadr x)) files))))
diff --git a/lisp/image/wallpaper.el b/lisp/image/wallpaper.el
new file mode 100644
index 00000000000..f083477ddf4
--- /dev/null
+++ b/lisp/image/wallpaper.el
@@ -0,0 +1,586 @@
+;;; wallpaper.el --- Change the desktop background -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Stefan Kangas <stefankangas@gmail.com>
+;; Keywords: images
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides the command `wallpaper-set', which sets the
+;; desktop background.
+;;
+;; On GNU/Linux and other Unix-like systems, it uses an external
+;; command to set the desktop background. This should work seamlessly
+;; on both X and Wayland.
+;;
+;; Finding an external command to use is obviously a bit tricky to get
+;; right, as there is no lack of platforms, window managers, desktop
+;; environments and tools. However, it should be detected
+;; automatically in most cases. If it doesn't work in your
+;; environment, customize the user options `wallpaper-command' and
+;; `wallpaper-command-args'.
+;;
+;; On MS-Windows, it uses the `w32-set-wallpaper' function, and on
+;; Haiku the `haiku-set-wallpaper' function, neither of which relies
+;; on any external commands. The value of `wallpaper-command' and
+;; `wallpaper-command-args' are ignored on such systems.
+;;
+;; On macOS, the "osascript" command is used. You might need to
+;; disable the option "Change picture" in the "Desktop & Screensaver"
+;; preferences for this to work (this was seen with macOS 10.13).
+;; You might also have to tweak some permissions.
+;;
+;; Note: If you find that you need to use a command in your
+;; environment that was not automatically detected, we would love to
+;; hear about it! Please send an email to bug-gnu-emacs@gnu.org and
+;; tell us the command (and all options) that worked for you. You can
+;; also use `M-x report-emacs-bug'.
+
+;;; Code:
+
+(eval-when-compile (require 'subr-x))
+(require 'xdg)
+(require 'cl-macs)
+
+(defvar wallpaper-debug nil
+ "If non-nil, display debug messages.")
+
+(defun wallpaper-debug (&rest args)
+ (when wallpaper-debug
+ (apply #'message
+ (concat "wallpaper-debug: " (car args))
+ (cdr args))))
+
+(defvar wallpaper-set-function
+ (cond ((fboundp 'w32-set-wallpaper)
+ #'w32-set-wallpaper)
+ ((and (fboundp 'haiku-set-wallpaper)
+ (featurep 'haiku))
+ 'haiku-set-wallpaper)
+ (#'wallpaper-default-set-function))
+ "Function used by `wallpaper-set' to set the wallpaper.
+The function takes one argument, FILE, which is the file name of
+the image file to set the wallpaper to.")
+
+(defun wallpaper--use-default-set-function-p ()
+ (eq wallpaper-set-function #'wallpaper-default-set-function))
+
+
+;;; Finding the wallpaper command
+
+(cl-defstruct (wallpaper-setter
+ ;; Get rid of the default constructor (`make-wallpaper-cmd').
+ (:constructor nil)
+ (:constructor
+ wallpaper-setter-create
+ ( name command args-raw
+ &rest rest-plist
+ &aux
+ (args (if (or (listp args-raw) (symbolp args-raw))
+ args-raw
+ (string-split args-raw)))
+ (predicate (plist-get rest-plist :predicate))
+ (init-action (plist-get rest-plist :init-action))
+ (detach (plist-get rest-plist :detach))))
+ (:copier wallpaper-setter-copy))
+ "Structure containing a method to set the wallpaper.
+
+NAME is a description of the setter (e.g. the name of the Desktop
+Environment).
+
+COMMAND is the executable to run to set the wallpaper.
+
+ARGS is the default list of command line arguments for COMMAND.
+
+PREDICATE is a function that will be called without any arguments
+and returns non-nil if this setter should be used.
+
+INIT-ACTION is a function that will be called without any
+arguments before trying to set the wallpaper.
+
+DETACH, if non-nil, means that the wallpaper process should
+continue running even after exiting Emacs."
+ name
+ command
+ args
+ (predicate #'always)
+ init-action
+ detach)
+
+;;;###autoload
+(put 'wallpaper-setter-create 'lisp-indent-function 1)
+
+(defun wallpaper--init-action-kill (process-name)
+ "Return kill function for `init-action' of a `wallpaper-setter' structure.
+The returned function kills any process named PROCESS-NAME owned
+by the current effective user id."
+ (lambda ()
+ (when-let ((procs
+ (seq-filter (lambda (p) (let-alist p
+ (and (= .euid (user-uid))
+ (equal .comm process-name))))
+ (mapcar (lambda (pid)
+ (cons (cons 'pid pid)
+ (process-attributes pid)))
+ (list-system-processes)))))
+ (dolist (proc procs)
+ (let-alist proc
+ (when (y-or-n-p (format "Kill \"%s\" process with PID %d?" .comm .pid))
+ (signal-process .pid 'TERM)))))))
+
+(defmacro wallpaper--default-methods-create (&rest items)
+ "Helper macro for defining `wallpaper--default-setters'."
+ (cons 'list
+ (mapcar
+ (lambda (item)
+ `(wallpaper-setter-create ,@item))
+ items)))
+
+(defvar wallpaper--default-setters
+ (wallpaper--default-methods-create
+
+ ;; macOS.
+ ;; NB. Should come first to override everything else.
+ ("macOS"
+ "osascript"
+ '("-e" "tell application \"Finder\" to set desktop picture to POSIX file \"%f\"")
+ :predicate (lambda ()
+ (eq system-type 'darwin)))
+
+ ;; Desktop environments.
+ ("Gnome"
+ "gsettings"
+ "set org.gnome.desktop.background picture-uri file://%F"
+ :predicate (lambda ()
+ (or (and (getenv "DESKTOP_SESSION")
+ (member (downcase (getenv "DESKTOP_SESSION"))
+ '("gnome" "gnome" "gnome-wayland" "gnome-xorg"
+ "unity" "ubuntu" "pantheon" "budgie-desktop"
+ "pop")))
+ (member "GNOME" (xdg-current-desktop))
+ (member "Budgie" (xdg-current-desktop))
+ (member "GNOME-Classic" (xdg-current-desktop)))))
+
+ ("KDE Plasma"
+ "plasma-apply-wallpaperimage" "%f"
+ :predicate (lambda ()
+ (member "KDE" (xdg-current-desktop))))
+
+ ("XFCE"
+ "xfconf-query" #'wallpaper-xfce-command-args
+ :predicate (lambda ()
+ (or (and (getenv "DESKTOP_SESSION")
+ (member (downcase (getenv "DESKTOP_SESSION"))
+ '("xubuntu" "ubuntustudio")))
+ (member "XFCE" (xdg-current-desktop)))))
+
+ ("LXDE"
+ "pcmanfm" "--set-wallpaper=%f"
+ :predicate (lambda ()
+ (member "LXDE" (xdg-current-desktop))))
+
+ ("LXQt"
+ "pcmanfm-qt" "--set-wallpaper=%f" ; "--wallpaper-mode=MODE"
+ :predicate (lambda ()
+ (or (member (and (getenv "DESKTOP_SESSION")
+ (downcase (getenv "DESKTOP_SESSION")))
+ '("lubuntu" "lxqt"))
+ (member "LXQt" (xdg-current-desktop)))))
+
+ ("Mate"
+ "gsettings" "set org.mate.background picture-filename %f"
+ :predicate (lambda ()
+ (or (and (getenv "DESKTOP_SESSION")
+ (equal "mate" (downcase (getenv "DESKTOP_SESSION"))))
+ (member "MATE" (xdg-current-desktop)))))
+
+ ("Cinnamon"
+ "gsettings" "set org.cinnamon.desktop.background picture-uri file://%F"
+ :predicate (lambda ()
+ (or (equal "cinnamon" (and (getenv "DESKTOP_SESSION")
+ (downcase (getenv "DESKTOP_SESSION"))))
+ (member "X-Cinnamon" (xdg-current-desktop)))))
+
+ ("Deepin"
+ "gsettings" "set com.deepin.wrap.gnome.desktop.background picture-uri file://%F"
+ :predicate (lambda ()
+ (member "Deepin" (xdg-current-desktop))))
+
+ ;; Wayland general.
+ ("Sway (Wayland)"
+ "swaybg" "-o * -i %f -m fill"
+ :predicate (lambda ()
+ (and (getenv "WAYLAND_DISPLAY")
+ (getenv "SWAYSOCK")))
+ :init-action (wallpaper--init-action-kill "swaybg")
+ :detach t)
+
+ ("wbg"
+ "wbg" "%f"
+ :predicate (lambda ()
+ (getenv "WAYLAND_DISPLAY"))
+ :init-action (wallpaper--init-action-kill "wbg")
+ :detach t)
+
+ ;; X general.
+ ("GraphicsMagick"
+ "gm" "display -size %wx%h -window root %f")
+
+ ("ImageMagick"
+ "display" "-resize %wx%h -window root %f")
+
+ ("feh"
+ "feh" "--bg-max %f")
+
+ ("fbsetbg"
+ "fbsetbg" "-a %f")
+
+ ("xwallpaper"
+ "xwallpaper" "--zoom %f")
+
+ ("hsetroot"
+ "hsetroot" "-full %f")
+
+ ("xloadimage"
+ "xloadimage" "-onroot -fullscreen %f")
+
+ ("xsetbg"
+ "xsetbg" "%f")
+ )
+ "List of setters used for setting the wallpaper.
+Every item in the list is a structure of type
+`wallpaper-setter' (which see).
+
+This is used by `wallpaper--find-command' to automatically set
+`wallpaper-command', and by `wallpaper--find-command-args' to set
+`wallpaper-command-args'. The setters will be tested in the
+order in which they appear.")
+
+(defun wallpaper-xfce-command-args ()
+ (let ((info
+ (with-temp-buffer
+ (call-process "xfconf-query" nil t nil
+ "-c" "xfce4-desktop"
+ "-p" "/backdrop/single-workspace-mode")
+ (buffer-string))))
+ (list "-c" "xfce4-desktop"
+ "-p" (format "/backdrop/screen%%S/monitor%%M/workspace%s/last-image"
+ (if (equal info "true")
+ "0"
+ "%W"))
+ "-s" "%f")))
+
+(defvar wallpaper--current-setter nil)
+
+(defun wallpaper--find-setter ()
+ (when (wallpaper--use-default-set-function-p)
+ (or (and (wallpaper-setter-p wallpaper--current-setter)
+ wallpaper--current-setter)
+ (setq wallpaper--current-setter
+ (catch 'found
+ (dolist (setter wallpaper--default-setters)
+ (wallpaper-debug "Testing setter %s" (wallpaper-setter-name setter))
+ (when (and (executable-find (wallpaper-setter-command setter))
+ (if-let ((pred (wallpaper-setter-predicate setter)))
+ (funcall pred)
+ t))
+ (wallpaper-debug "Found setter %s" (wallpaper-setter-name setter))
+ (throw 'found setter))))))))
+
+(defun wallpaper--find-command ()
+ "Return a valid command to set the wallpaper in this environment."
+ (when-let ((setter (wallpaper--find-setter)))
+ (wallpaper-setter-command setter)))
+
+(defun wallpaper--find-command-args ()
+ "Return command line arguments matching `wallpaper-command'."
+ (when-let ((setter (wallpaper--find-setter)))
+ (wallpaper-setter-args setter)))
+
+
+;;; Customizable variables
+
+(defvar wallpaper-command-args) ; silence byte-compiler
+(defun wallpaper--set-wallpaper-command (sym val)
+ "Set `wallpaper-command', and update `wallpaper-command-args'.
+Used to set `wallpaper-command'."
+ ;; Note: `wallpaper-command' is used by `wallpaper--find-command-args'.
+ (prog1 (set-default sym val)
+ (set-default 'wallpaper-command-args
+ (wallpaper--find-command-args))))
+
+(defcustom wallpaper-command (wallpaper--find-command)
+ "Executable used by `wallpaper-set' for setting the wallpaper.
+A suitable command for your environment should be detected
+automatically, so there is usually no need to customize this.
+
+If you set this to any supported command using customize or
+`setopt', the user option `wallpaper-command-args' is
+automatically updated to match. If you need to change this to an
+unsupported command, you will want to manually customize
+`wallpaper-command-args' to match.
+
+The value of this variable is ignored on MS-Windows and Haiku
+systems, where a native API is used instead."
+ :type
+ '(choice
+ (radio
+ (const :tag "gsettings (GNOME)" "gsettings")
+ (const :tag "plasma-apply-wallpaperimage (KDE Plasma)" "plasma-apply-wallpaperimage")
+ (const :tag "xfconf-query (XFCE)" "xfconf-query")
+ (const :tag "pcmanf (LXDE)" "pcmanf")
+ (const :tag "pcmanf-qt (LXQt)" "pcmanf-qt")
+ (const :tag "swaybg (Wayland/Sway)" "swaybg")
+ (const :tag "wbg (Wayland)" "wbg")
+ (const :tag "gm (X Window System)" "gm")
+ (const :tag "display (X Window System)" "display")
+ (const :tag "feh (X Window System)" "feh")
+ (const :tag "fbsetbg (X Window System)" "fbsetbg")
+ (const :tag "xwallpaper (X Window System)" "xwallpaper")
+ (const :tag "hsetroot (X Window System)" "hsetroot")
+ (const :tag "xloadimage (X Window System)" "xloadimage")
+ (const :tag "xsetbg (X Window System)" "xsetbg")
+ (const :tag "osascript (macOS)" "osascript"))
+ (const :tag "Other (specify)" string)
+ (const :tag "None" nil))
+ :set #'wallpaper--set-wallpaper-command
+ :group 'image
+ :version "29.1")
+
+(defcustom wallpaper-command-args (wallpaper--find-command-args)
+ "Command line arguments for `wallpaper-command'.
+A suitable command for your environment should be detected
+automatically, so there is usually no need to customize this.
+However, if you do need to change this, you might also want to
+customize `wallpaper-command' to match.
+
+The value is a list of command list arguments to use, or a
+function that returns a list of command line arguments.
+
+In each command line argument, these specifiers will be replaced:
+
+ %f full file name
+ %h height of the selected frame's display (as returned
+ by `display-pixel-height')
+ %w the width of the selected frame's display (as returned
+ by `display-pixel-width').
+ %F full file name URI-encoded
+ %S current X screen (e.g. \"0\")
+ %W current workspace (e.g., \"0\")
+ %M name of the monitor (e.g., \"0\" or \"LVDS\")
+
+If `wallpaper-set' is run from a TTY frame, instead prompt for a
+height and width to use for %h and %w.
+
+The value of this variable is ignored on MS-Windows and Haiku
+systems, where a native API is used instead."
+ :type '(choice (repeat string)
+ function)
+ :group 'image
+ :version "29.1")
+
+
+;;; Utility functions
+
+(defvar wallpaper-default-width 1080
+ "Default width used by `wallpaper-set'.
+This is only used when it can't be detected automatically.
+See also `wallpaper-default-height'.")
+
+(defvar wallpaper-default-height 1920
+ "Default height used by `wallpaper-set'.
+This is only used when it can't be detected automatically.
+See also `wallpaper-default-width'.")
+
+(defun wallpaper--get-height-or-width (desc fun default)
+ (cond ((display-graphic-p) (funcall fun))
+ (noninteractive default)
+ ((read-number (format "Wallpaper %s in pixels: " desc) default))))
+
+(autoload 'ffap-file-at-point "ffap")
+
+(defvar wallpaper-image-file-extensions
+ '("bmp" "gif" "heif" "jpeg" "jpg" "png" "tif" "tiff" "webp")
+ "List of file extensions that `wallpaper-set' will consider for completion.")
+
+(defun wallpaper--image-file-regexp ()
+ (rx-to-string '(: "." (eval `(or ,@wallpaper-image-file-extensions)) eos) t))
+
+(defun wallpaper--get-default-file ()
+ (catch 'found
+ (dolist (file (list buffer-file-name (ffap-file-at-point)))
+ (when (and file (string-match (wallpaper--image-file-regexp) file))
+ (throw 'found (abbreviate-file-name
+ (expand-file-name file)))))))
+
+
+;;; wallpaper-set
+
+(defun wallpaper--x-monitor-name ()
+ "Get the monitor name for `wallpaper-set'.
+On a graphical display, try using the same monitor as the current
+frame.
+On a non-graphical display, try to get the name by connecting to
+the display server directly, and run \"xrandr\" if that doesn't
+work. Prompt for the monitor name if neither method works.
+
+This function is meaningful only on X and is used only there."
+ (if (or (display-graphic-p)
+ noninteractive)
+ (let-alist (car (display-monitor-attributes-list))
+ (if (and .name (member .source '("XRandr" "XRandR 1.5" "Gdk")))
+ .name
+ "0"))
+ (if-let ((name
+ (and (getenv "DISPLAY")
+ (or
+ (cdr (assq 'name
+ (progn
+ (x-open-connection (getenv "DISPLAY"))
+ (car (display-monitor-attributes-list
+ (car (last (terminal-list))))))))
+ (and (executable-find "xrandr")
+ (with-temp-buffer
+ (call-process "xrandr" nil t nil)
+ (goto-char (point-min))
+ (re-search-forward (rx bol
+ (group (+ (not (in " \n"))))
+ " connected")
+ nil t)
+ (match-string 1)))))))
+ ;; Prefer "0" to "default" as that works in XFCE.
+ (if (equal name "default") "0" name)
+ (read-string (format-prompt "Monitor name" nil)))))
+
+(defun wallpaper--format-arg (format file)
+ "Format a `wallpaper-command-args' argument ARG.
+FILE is the image file name."
+ (format-spec
+ format
+ `((?f . ,(expand-file-name file))
+ (?F . ,(lambda ()
+ (mapconcat #'url-hexify-string
+ (file-name-split file)
+ "/")))
+ (?h . ,(lambda ()
+ (wallpaper--get-height-or-width
+ "height"
+ #'display-pixel-height
+ wallpaper-default-height)))
+ (?w . ,(lambda ()
+ (wallpaper--get-height-or-width
+ "width"
+ #'display-pixel-width
+ wallpaper-default-width)))
+ ;; screen number
+ (?S . ,(lambda ()
+ (let ((display (frame-parameter (selected-frame) 'display)))
+ (if (and display
+ (string-match (rx ":" (+ (in "0-9")) "."
+ (group (+ (in "0-9"))) eos)
+ display))
+ (match-string 1 display)
+ "0"))))
+ ;; monitor name
+ (?M . ,#'wallpaper--x-monitor-name)
+ ;; workspace
+ (?W . ,(lambda ()
+ (or (and (fboundp 'x-window-property)
+ (display-graphic-p)
+ (number-to-string
+ (or (x-window-property "_NET_CURRENT_DESKTOP" nil "CARDINAL" 0 nil t)
+ (x-window-property "WIN_WORKSPACE" nil "CARDINAL" 0 nil t)
+ 0)))
+ "0"))))))
+
+(defun wallpaper-default-set-function (file)
+ "Set the wallpaper to FILE using a command.
+This is the default function for `wallpaper-set-function'."
+ (unless wallpaper-command
+ (error "Couldn't find a command to set the wallpaper with"))
+ (let* ((args (if (functionp wallpaper-command-args)
+ (funcall wallpaper-command-args)
+ wallpaper-command-args))
+ (real-args (mapcar (lambda (arg) (wallpaper--format-arg arg file))
+ args))
+ (bufname (format " *wallpaper-%s*" (random)))
+ (setter (and (wallpaper-setter-p wallpaper--current-setter)
+ (equal (wallpaper-setter-command wallpaper--current-setter)
+ wallpaper-command)
+ wallpaper--current-setter))
+ (init-action (and setter (wallpaper-setter-init-action setter)))
+ (detach (and setter (wallpaper-setter-detach setter)))
+ process)
+ (when init-action
+ (funcall init-action))
+ (wallpaper-debug "Using command: \"%s %s\""
+ wallpaper-command (string-join real-args " "))
+ (if detach
+ (apply #'call-process wallpaper-command nil 0 nil real-args)
+ (setq process
+ (apply #'start-process "set-wallpaper" bufname
+ wallpaper-command real-args))
+ (setf (process-sentinel process)
+ (lambda (process status)
+ (unwind-protect
+ (if (and (eq (process-status process) 'exit)
+ (zerop (process-exit-status process)))
+ (message "Desktop wallpaper changed to %s"
+ (abbreviate-file-name file))
+ (message "command \"%s %s\": %S"
+ (string-join (process-command process) " ")
+ (string-replace "\n" "" status)
+ (with-current-buffer (process-buffer process)
+ (string-clean-whitespace (buffer-string)))))
+ (ignore-errors
+ (kill-buffer (process-buffer process)))))))
+ process))
+
+;;;###autoload
+(defun wallpaper-set (file)
+ "Set the desktop background to FILE in a graphical environment.
+
+On GNU/Linux and other Unix-like systems, this relies on an
+external command. Which command to use is automatically detected
+in most cases, but can be manually customized with the user
+options `wallpaper-command' and `wallpaper-command-args'.
+
+On MS-Windows and Haiku systems, no external command is needed,
+so the value of `wallpaper-commands' is ignored."
+ (interactive
+ (let ((default (wallpaper--get-default-file)))
+ (list (read-file-name (format-prompt "Set desktop background to" default)
+ default-directory default
+ t nil
+ (let ((re (wallpaper--image-file-regexp)))
+ (lambda (file-name)
+ (or (file-directory-p file-name)
+ (string-match re file-name))))))))
+ (when (file-directory-p file)
+ (error "Can't set wallpaper to a directory: %s" file))
+ (unless (file-exists-p file)
+ (error "No such file: %s" file))
+ (unless (file-readable-p file)
+ (error "File is not readable: %s" file))
+ (wallpaper-debug "Using image %S:" file)
+ (funcall wallpaper-set-function file))
+
+(provide 'wallpaper)
+
+;;; wallpaper.el ends here
diff --git a/lisp/imenu.el b/lisp/imenu.el
index dcd816cb7a8..7f68bd15b96 100644
--- a/lisp/imenu.el
+++ b/lisp/imenu.el
@@ -209,6 +209,13 @@ called within a `save-excursion'.
See `imenu--index-alist' for the format of the buffer index alist.")
;;;###autoload
+(defvar-local imenu-submenus-on-top t
+ "Flag specifying whether items with sublists should be kept at top.
+
+For some indexes, such as those describing sections in a document, it
+makes sense to keep their original order even in the menubar.")
+
+;;;###autoload
(defvar-local imenu-prev-index-position-function 'beginning-of-defun
"Function for finding the next index position.
@@ -310,7 +317,7 @@ element recalculates the buffer's index alist.")
(defvar imenu--history-list nil
;; Making this buffer local caused it not to work!
- "History list for `jump-to-function-in-buffer'.")
+ "History list for `imenu-choose-buffer-index'.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
@@ -373,10 +380,11 @@ The returned alist DOES NOT share structure with MENULIST."
(if (memq imenu--rescan-item menulist)
(setq keep-at-top (list imenu--rescan-item)
menulist (delq imenu--rescan-item menulist)))
- (dolist (item menulist)
- (when (imenu--subalist-p item)
- (push item keep-at-top)
- (setq menulist (delq item menulist))))
+ (if imenu-submenus-on-top
+ (dolist (item menulist)
+ (when (imenu--subalist-p item)
+ (push item keep-at-top)
+ (setq menulist (delq item menulist)))))
(if imenu-sort-function
(setq menulist (sort menulist imenu-sort-function)))
(if (> (length menulist) imenu-max-items)
diff --git a/lisp/indent.el b/lisp/indent.el
index b0c1a021da7..c7ec5c9a3ed 100644
--- a/lisp/indent.el
+++ b/lisp/indent.el
@@ -695,12 +695,10 @@ A value of nil means a tab stop every `tab-width' columns."
:safe 'listp
:type '(repeat integer))
-(defvar edit-tab-stops-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-x\C-s" 'edit-tab-stops-note-changes)
- (define-key map "\C-c\C-c" 'edit-tab-stops-note-changes)
- map)
- "Keymap used in `edit-tab-stops'.")
+(defvar-keymap edit-tab-stops-map
+ :doc "Keymap used in `edit-tab-stops'."
+ "C-x C-s" #'edit-tab-stops-note-changes
+ "C-c C-c" #'edit-tab-stops-note-changes)
(defvar edit-tab-stops-buffer nil
"Buffer whose tab stops are being edited.
diff --git a/lisp/info.el b/lisp/info.el
index 292bf93a6f4..fabba2734a3 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -763,6 +763,11 @@ See a list of available Info commands in `Info-mode'."
(read-file-name "Info file name: " nil nil t))
(if (numberp current-prefix-arg)
(format "*info*<%s>" current-prefix-arg))))
+ (when file-or-node
+ ;; Info node names don't contain newlines, so allow for easier use
+ ;; of names that might have been wrapped (in emails, etc.).
+ (setq file-or-node
+ (string-replace "\n" " " file-or-node)))
(info-setup file-or-node
(pop-to-buffer-same-window (or buffer "*info*"))))
diff --git a/lisp/international/characters.el b/lisp/international/characters.el
index 245ade54e18..9dcae187f21 100644
--- a/lisp/international/characters.el
+++ b/lisp/international/characters.el
@@ -152,6 +152,9 @@ with L, LRE, or LRO Unicode bidi character type.")
(modify-category-entry '(#x20000 . #x2FFFF) ?|)
(modify-category-entry '(#x20000 . #x2FFFF) ?C)
(modify-category-entry '(#x20000 . #x2FFFF) ?c)
+(modify-category-entry '(#x30000 . #x323AF) ?|)
+(modify-category-entry '(#x30000 . #x323AF) ?C)
+(modify-category-entry '(#x30000 . #x323AF) ?c)
;; Chinese character set (GB2312)
@@ -227,7 +230,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(modify-category-entry #x1B001 ?H)
(modify-category-entry #x1B11F ?H)
(modify-category-entry '(#x1B150 . #x1B152) ?H)
-(modify-category-entry '(#x1B002 . #x1B11E) ?H) ; Hentiagana
+(modify-category-entry '(#x1B002 . #x1B11E) ?H) ; Hentaigana
(modify-category-entry '(#x1AFF0 . #x1B1FF) ?j)
@@ -306,6 +309,7 @@ with L, LRE, or LRO Unicode bidi character type.")
(modify-category-entry '(#xfb50 . #xfdcf) ?b)
(modify-category-entry '(#xfdf0 . #xfdff) ?b)
(modify-category-entry '(#xfe70 . #xfefe) ?b)
+(modify-category-entry '(#x10ec0 . #x10eff) ?b)
;; Cyrillic character set (ISO-8859-5)
@@ -615,6 +619,9 @@ with L, LRE, or LRO Unicode bidi character type.")
;; Cyrillic Extended-C
(modify-category-entry '(#x1C80 . #x1C8F) ?y)
+ ;; Cyrillic Extended-D
+ (modify-category-entry '(#x1E030 . #x1E08F) ?y)
+
;; space characters (see section 6.2 in the Unicode Standard)
(set-case-syntax ?  " " tbl)
(setq c #x2000)
@@ -1283,16 +1290,24 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x2B1B . #x2B1C)
(#x2B50 . #x2B50)
(#x2B55 . #x2B55)
- (#x2E80 . #x303E)
- (#x3040 . #x3247)
+ (#x2E80 . #x2E99)
+ (#x2E9B . #x2EF3)
+ (#x2F00 . #x2FD5)
+ (#x2FF0 . #x2FFB)
+ (#x3000 . #x303E)
+ (#x3041 . #x3096)
+ (#x3099 . #x30FF)
+ (#x3105 . #x312F)
+ (#x3131 . #x31E3)
+ (#x31F0 . #x3247)
(#x3250 . #x4DBF)
- (#x4E00 . #x9FFF)
+ (#x4E00 . #xA48C)
(#xA490 . #xA4C6)
- (#xA960 . #xA97F)
+ (#xA960 . #xA97C)
(#xAC00 . #xD7A3)
(#xF900 . #xFAFF)
(#xFE10 . #xFE19)
- (#xFE30 . #xFE6F)
+ (#xFE30 . #xFE6B)
(#xFF01 . #xFF60)
(#xFFE0 . #xFFE6)
(#x16FE0 . #x16FE4)
@@ -1300,8 +1315,14 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x17000 . #x187F7)
(#x18800 . #x18AFF)
(#x18B00 . #x18CD5)
- (#x1AFF0 . #x1AFFF)
- (#x1B000 . #x1B152)
+ (#x18D00 . #x18D08)
+ (#x1AFF0 . #x1AFF3)
+ (#x1AFF5 . #x1AFFB)
+ (#x1AFFD . #x1AFFE)
+ (#x1B000 . #x1B122)
+ (#x1B132 . #x1B132)
+ (#x1B150 . #x1B152)
+ (#x1B155 . #x1B155)
(#x1B164 . #x1B167)
(#x1B170 . #x1B2FB)
(#x1F004 . #x1F004)
@@ -1309,7 +1330,12 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x1F18E . #x1F18E)
(#x1F191 . #x1F19A)
(#x1F1AD . #x1F1AD)
- (#x1F200 . #x1F320)
+ (#x1F200 . #x1F202)
+ (#x1F210 . #x1F23B)
+ (#x1F240 . #x1F248)
+ (#x1F250 . #x1F251)
+ (#x1F260 . #x1F265)
+ (#x1F300 . #x1F320)
(#x1F32D . #x1F335)
(#x1F337 . #x1F37C)
(#x1F37E . #x1F393)
@@ -1334,10 +1360,11 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x1F6CC . #x1F6CC)
(#x1F6D0 . #x1F6D2)
(#x1F6D5 . #x1F6D7)
- (#x1F6DD . #x1F6DF)
+ (#x1F6DC . #x1F6DF)
(#x1F6EB . #x1F6EC)
(#x1F6F4 . #x1F6FC)
- (#x1F7E0 . #x1F7F0)
+ (#x1F7E0 . #x1F7EB)
+ (#x1F7F0 . #x1F7F0)
(#x1F90C . #x1F93A)
(#x1F93C . #x1F945)
(#x1F947 . #x1F9FF)
@@ -1345,13 +1372,12 @@ with L, LRE, or LRO Unicode bidi character type.")
(#x1FA60 . #x1FA6D)
(#x1FA70 . #x1FA74)
(#x1FA78 . #x1FA7C)
- (#x1FA80 . #x1FA86)
- (#x1FA90 . #x1FAAC)
- (#x1FAB0 . #x1FABA)
- (#x1FAC0 . #x1FAC5)
- (#x1FAD0 . #x1FAD9)
- (#x1FAE0 . #x1FAE7)
- (#x1FAF0 . #x1FAF6)
+ (#x1FA80 . #x1FA88)
+ (#x1FA90 . #x1FABD)
+ (#x1FABF . #x1FAC5)
+ (#x1FACE . #x1FADB)
+ (#x1FAE0 . #x1FAE8)
+ (#x1FAF0 . #x1FAF8)
(#x1FB00 . #x1FB92)
(#x20000 . #x2FFFF)
(#x30000 . #x3FFFF))))
diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el
index 8d34aa99c39..93fedb8c1ad 100644
--- a/lisp/international/fontset.el
+++ b/lisp/international/fontset.el
@@ -152,7 +152,7 @@
'((latin ?A ?Z ?a ?z #x00C0 #x0100 #x0180 #x1e00)
(phonetic #x250 #x283)
(greek #x3A9)
- (coptic #x3E2)
+ (coptic #x3E2 #x2C80 #x2CAE)
(cyrillic #x42F)
(armenian #x531)
(hebrew #x5D0)
@@ -221,6 +221,7 @@
(lycian #x10280)
(carian #x102A0)
(old-italic #x10300)
+ (gothic #x10330 #x10348)
(ugaritic #x10380)
(old-permic #x10350)
(old-persian #x103A0)
@@ -270,6 +271,7 @@
(masaram-gondi #x11D00)
(gunjala-gondi #x11D60)
(makasar #x11EE0 #x11EF7)
+ (kawi #x11F04 #x11F41 #x11F4F)
(cuneiform #x12000)
(cypro-minoan #x12F90)
(egyptian #x13000)
@@ -286,18 +288,21 @@
(byzantine-musical-symbol #x1D000)
(musical-symbol #x1D100)
(ancient-greek-musical-notation #x1D200)
+ (kaktovik-numeral #x1D2C0)
(tai-xuan-jing-symbol #x1D300)
(counting-rod-numeral #x1D360)
(nyiakeng-puachue-hmong #x1e100)
- (toto #x1E290)
- (wancho #x1e2c0)
- (mende-kikakui #x1E810)
- (adlam #x1E900)
- (indic-siyaq-number #x1ec71)
- (ottoman-siyaq-number #x1ed01)
+ (toto #x1E290 #x1E295 #x1E2AD)
+ (wancho #x1E2C0 #x1E2E8 #x1E2EF)
+ (nag-mundari #x1E4D0 #x1E4EB #x1E4F0)
+ (mende-kikakui #x1E810 #x1E8A6)
+ (adlam #x1E900 #x1E943)
+ (indic-siyaq-number #x1EC71 #x1EC9F)
+ (ottoman-siyaq-number #x1ED01 #x1ED27)
(mahjong-tile #x1F000)
(domino-tile #x1F030)
- (emoji #x1F300 #x1F600)))
+ (emoji #x1F300 #x1F600)
+ (chess-symbol . [#x1FA00 #x1FA67])))
(defvar otf-script-alist)
@@ -371,6 +376,7 @@
(knda . kannada)
(knd2 . kannada)
(kana . kana) ; Hiragana
+ (kawi . kawi)
(kali . kayah-li)
(khar . kharoshthi)
(kits . khitan-small-script)
@@ -410,6 +416,7 @@
(mymr . burmese)
(nand . nandinagari)
(nbat . nabataean)
+ (nagm . nag-mundari)
(newa . newa)
(nko\ . nko)
(nshu . nushu)
@@ -772,6 +779,7 @@
lepcha
symbol
braille
+ coptic
yi
syloti-nagri
rejang
@@ -785,6 +793,7 @@
lycian
carian
old-italic
+ gothic
ugaritic
old-persian
deseret
@@ -810,6 +819,7 @@
siddham
modi
makasar
+ kawi
dives-akuru
cuneiform
egyptian
@@ -821,14 +831,21 @@
byzantine-musical-symbol
musical-symbol
ancient-greek-musical-notation
+ kaktovik-numeral
tai-xuan-jing-symbol
counting-rod-numeral
toto
+ wancho
+ nag-mundari
+ mende-kikakui
adlam
tai-tham
+ indic-siyaq-number
+ ottoman-siyaq-number
mahjong-tile
domino-tile
- emoji))
+ emoji
+ chess-symbol))
(set-fontset-font "fontset-default"
script (font-spec :registry "iso10646-1" :script script)
nil 'append))
@@ -974,7 +991,11 @@
(set-fontset-font "fontset-default" symbol-subgroup
"-*-fixed-medium-*-*-*-*-*-*-*-*-*-iso10646-1"
nil 'prepend))
- ;; This sets up the Emoji codepoints to use prettier fonts.
+ ;; This sets up the Emoji codepoints to use prettier fonts:
+ ;; this is fallback, if they don't have color Emoji capabilities...
+ (set-fontset-font "fontset-default" 'emoji
+ '("Noto Emoji" . "iso10646-1") nil 'prepend)
+ ;; ...and this is if they do
(set-fontset-font "fontset-default" 'emoji
'("Noto Color Emoji" . "iso10646-1") nil 'prepend)
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index e1d0df6e3ed..48e5c9aa1fe 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -1909,8 +1909,11 @@ The default status is as follows:
(reset-language-environment)
-(defun set-display-table-and-terminal-coding-system (language-name &optional coding-system display)
- "Set up the display table and terminal coding system for LANGUAGE-NAME."
+(defun set-display-table-and-terminal-coding-system (language-name
+ &optional coding-system
+ display inhibit-refresh)
+ "Set up the display table and terminal coding system for LANGUAGE-NAME.
+If INHIBIT-REFRESH, don't redraw the current frame."
(let ((coding (get-language-info language-name 'unibyte-display)))
(if (and coding
(or (not coding-system)
@@ -1923,7 +1926,8 @@ The default status is as follows:
(when standard-display-table
(dotimes (i 128)
(aset standard-display-table (+ i 128) nil))))
- (set-terminal-coding-system (or coding-system coding) display)))
+ (set-terminal-coding-system (or coding-system coding) display
+ inhibit-refresh)))
(defun set-language-environment (language-name)
"Set up multilingual environment for using LANGUAGE-NAME.
@@ -2660,17 +2664,23 @@ For example, translate \"swedish\" into \"sv_SE.ISO8859-1\"."
"The currently set locale environment.")
(defmacro with-locale-environment (locale-name &rest body)
- "Execute BODY with the locale set to LOCALE-NAME."
+ "Execute BODY with the locale set to LOCALE-NAME.
+
+Note that changing the locale modifies settings that affect
+the display, such as `terminal-coding-system' and `standard-display-table',
+but this macro does not by itself perform redisplay. If BODY needs to
+display something with LOCALE-NAME's settings, include a call
+to `redraw-frame' in BODY."
(declare (indent 1) (debug (sexp def-body)))
(let ((current (gensym)))
`(let ((,current current-locale-environment))
(unwind-protect
(progn
- (set-locale-environment ,locale-name)
+ (set-locale-environment ,locale-name nil t)
,@body)
- (set-locale-environment ,current)))))
+ (set-locale-environment ,current nil t)))))
-(defun set-locale-environment (&optional locale-name frame)
+(defun set-locale-environment (&optional locale-name frame inhibit-refresh)
"Set up multilingual environment for using LOCALE-NAME.
This sets the language environment, the coding system priority,
the default input method and sometimes other things.
@@ -2699,6 +2709,9 @@ This function sets the `current-locale-environment' variable. To
change the locale temporarily, `with-locale-environment' can be
used.
+By default, this function will redraw the current frame. If
+INHIBIT-REFRESH is non-nil, this isn't done.
+
See also `locale-charset-language-names', `locale-language-names',
`locale-preferred-coding-systems' and `locale-coding-system'."
(interactive (list (completing-read "Set environment for locale: "
@@ -2808,7 +2821,7 @@ See also `locale-charset-language-names', `locale-language-names',
(set-language-environment language-name))
(set-display-table-and-terminal-coding-system
- language-name coding-system frame)
+ language-name coding-system frame inhibit-refresh)
;; Set the `keyboard-coding-system' if appropriate (tty
;; only). At least X and MS Windows can generate
@@ -2865,7 +2878,7 @@ See also `locale-charset-language-names', `locale-language-names',
(or output-coding (setq output-coding code-page-coding))
(unless frame (setq locale-coding-system locale-coding))
(set-keyboard-coding-system code-page-coding frame)
- (set-terminal-coding-system output-coding frame)
+ (set-terminal-coding-system output-coding frame inhibit-refresh)
(setq default-file-name-coding-system ansi-code-page-coding))))
(when (eq system-type 'darwin)
@@ -2876,7 +2889,7 @@ See also `locale-charset-language-names', `locale-language-names',
;; the locale.
(when (and (null window-system)
(equal (getenv "TERM_PROGRAM" frame) "Apple_Terminal"))
- (set-terminal-coding-system 'utf-8)
+ (set-terminal-coding-system 'utf-8 nil inhibit-refresh)
(set-keyboard-coding-system 'utf-8)))
;; Default to A4 paper if we're not in a C, POSIX or US locale.
diff --git a/lisp/international/mule.el b/lisp/international/mule.el
index ab74c2cffd9..6a794a84101 100644
--- a/lisp/international/mule.el
+++ b/lisp/international/mule.el
@@ -767,7 +767,7 @@ VALUE must be a translation table to use on encoding.
VALUE must be a function to call after some text is inserted and
decoded by the coding system itself and before any functions in
-`after-insert-functions' are called. This function is passed one
+`after-insert-file-functions' are called. This function is passed one
argument: the number of characters in the text to convert, with
point at the start of the text. The function should leave point
and the match data unchanged, and should return the new character
@@ -1362,7 +1362,8 @@ to CODING-SYSTEM."
This is normally set according to the selected language environment.
See also the command `set-terminal-coding-system'.")
-(defun set-terminal-coding-system (coding-system &optional terminal)
+(defun set-terminal-coding-system (coding-system &optional terminal
+ inhibit-refresh)
"Set coding system of terminal output to CODING-SYSTEM.
All text output to TERMINAL will be encoded
with the specified coding system.
@@ -1371,9 +1372,12 @@ For a list of possible values of CODING-SYSTEM, use \\[list-coding-systems].
The default is determined by the selected language environment
or by the previous use of this command.
-TERMINAL may be a terminal object, a frame, or nil for the
-selected frame's terminal. The setting has no effect on
-graphical terminals."
+Optional argument TERMINAL may be a terminal object or a frame,
+and defaults to the selected frame's terminal. The setting has no
+effect on graphical terminals.
+
+By default, this function will redraw the current frame;
+optional argument INHIBIT-REFRESH, if non-nil, prevents that."
(interactive
(list (let ((default (if (and (not (terminal-coding-system))
default-terminal-coding-system)
@@ -1387,7 +1391,8 @@ graphical terminals."
(if coding-system
(setq default-terminal-coding-system coding-system))
(set-terminal-coding-system-internal coding-system terminal)
- (redraw-frame))
+ (unless inhibit-refresh
+ (redraw-frame)))
(defvar default-keyboard-coding-system nil
"Default value of the keyboard coding system.
diff --git a/lisp/international/rfc1843.el b/lisp/international/rfc1843.el
index 5050b7c030a..73b610c0341 100644
--- a/lisp/international/rfc1843.el
+++ b/lisp/international/rfc1843.el
@@ -1,4 +1,4 @@
-;;; rfc1843.el --- HZ (rfc1843) decoding -*- lexical-binding:t -*-
+;;; rfc1843.el --- HZ (RFC 1843) decoding -*- lexical-binding:t -*-
;; Copyright (C) 1998-2022 Free Software Foundation, Inc.
@@ -22,6 +22,9 @@
;;; Commentary:
+;; HZ (RFC 1843) decoding. HZ is a data format for exchanging files
+;; of arbitrarily mixed Chinese and ASCII characters.
+;;
;; Test:
;; (rfc1843-decode-string "~{<:Ky2;S{#,NpJ)l6HK!#~}")
diff --git a/lisp/international/textsec-check.el b/lisp/international/textsec-check.el
index 567ef73feb2..99ffd397e23 100644
--- a/lisp/international/textsec-check.el
+++ b/lisp/international/textsec-check.el
@@ -35,7 +35,7 @@ If nil, these checks are disabled."
:version "29.1")
(defface textsec-suspicious
- '((t (:weight bold :background "red")))
+ '((t (:weight bold :background "red" :foreground "white")))
"Face used to highlight suspicious strings.")
;;;###autoload
diff --git a/lisp/international/titdic-cnv.el b/lisp/international/titdic-cnv.el
index 080045e7520..d2a6ee1e9d1 100644
--- a/lisp/international/titdic-cnv.el
+++ b/lisp/international/titdic-cnv.el
@@ -281,7 +281,7 @@ SPC, 6, 3, 4, or 7 specifying a tone (SPC:陰平, 6:陽平, 3:上聲, 4:去聲,
(while (not (eobp))
(let ((ch (following-char))
(pos (point)))
- (cond ((= ch ?C) ; COMMENT
+ (cond ((eq ch ?C) ; COMMENT
(cond ((looking-at "COMMENT")
(let ((pos (match-end 0))
(to (progn (end-of-line) (point))))
@@ -295,7 +295,7 @@ SPC, 6, 3, 4, or 7 specifying a tone (SPC:陰平, 6:陽平, 3:上聲, 4:去聲,
(setq tit-comments
(cons (buffer-substring-no-properties pos (point))
tit-comments))))))
- ((= ch ?M) ; MULTICHOICE, MOVERIGHT, MOVELEFT
+ ((eq ch ?M) ; MULTICHOICE, MOVERIGHT, MOVELEFT
(cond ((looking-at "MULTICHOICE:[ \t]*")
(goto-char (match-end 0))
(setq tit-multichoice (looking-at "YES")))
@@ -305,7 +305,7 @@ SPC, 6, 3, 4, or 7 specifying a tone (SPC:陰平, 6:陽平, 3:上聲, 4:去聲,
((looking-at "MOVELEFT:[ \t]*")
(goto-char (match-end 0))
(setq tit-moveleft (tit-read-key-value)))))
- ((= ch ?P) ; PROMPT
+ ((eq ch ?P) ; PROMPT
(cond ((looking-at "PROMPT:[ \t]*")
(goto-char (match-end 0))
(setq tit-prompt (tit-read-key-value))
@@ -316,7 +316,7 @@ SPC, 6, 3, 4, or 7 specifying a tone (SPC:陰平, 6:陽平, 3:上聲, 4:去聲,
(if (or (eq (nth 1 split) 32)
(eq (nth 2 split) 32))
(setq tit-prompt (substring tit-prompt 0 -1)))))))
- ((= ch ?B) ; BACKSPACE, BEGINDICTIONARY,
+ ((eq ch ?B) ; BACKSPACE, BEGINDICTIONARY,
; BEGINPHRASE
(cond ((looking-at "BACKSPACE:[ \t]*")
(goto-char (match-end 0))
@@ -325,7 +325,7 @@ SPC, 6, 3, 4, or 7 specifying a tone (SPC:陰平, 6:陽平, 3:上聲, 4:去聲,
(setq tit-dictionary t))
((looking-at "BEGINPHRASE")
(setq tit-dictionary nil))))
- ((= ch ?K) ; KEYPROMPT
+ ((eq ch ?K) ; KEYPROMPT
(cond ((looking-at "KEYPROMPT(\\(.*\\)):[ \t]*")
(let ((key-char (match-string 1)))
(goto-char (match-end 0))
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 2ef35438e91..bc3697deb0a 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -832,17 +832,15 @@ This is like `describe-bindings', but displays only Isearch keys."
:image '(isearch-tool-bar-image "left-arrow")))
map))
-(defvar minibuffer-local-isearch-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map minibuffer-local-map)
- (define-key map "\r" 'exit-minibuffer)
- (define-key map "\M-\t" 'isearch-complete-edit)
- (define-key map "\C-s" 'isearch-forward-exit-minibuffer)
- (define-key map "\C-r" 'isearch-reverse-exit-minibuffer)
- (define-key map "\C-f" 'isearch-yank-char-in-minibuffer)
- (define-key map [right] 'isearch-yank-char-in-minibuffer)
- map)
- "Keymap for editing Isearch strings in the minibuffer.")
+(defvar-keymap minibuffer-local-isearch-map
+ :doc "Keymap for editing Isearch strings in the minibuffer."
+ :parent minibuffer-local-map
+ "RET" #'exit-minibuffer
+ "M-TAB" #'isearch-complete-edit
+ "C-s" #'isearch-forward-exit-minibuffer
+ "C-r" #'isearch-reverse-exit-minibuffer
+ "C-f" #'isearch-yank-char-in-minibuffer
+ "<right>" #'isearch-yank-char-in-minibuffer)
;; Internal variables declared globally for byte-compiler.
;; These are all set with setq while isearching
@@ -3651,8 +3649,7 @@ Optional third argument, if t, means if fail just return nil (no error).
(setq isearch-case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp)))
(condition-case lossage
- (let ((inhibit-point-motion-hooks isearch-invisible)
- (inhibit-quit nil)
+ (let ((inhibit-quit nil)
(case-fold-search isearch-case-fold-search)
(search-invisible isearch-invisible)
(retry t))
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el
index 6ef46ad60b7..ed7a3dbba34 100644
--- a/lisp/jit-lock.el
+++ b/lisp/jit-lock.el
@@ -27,16 +27,6 @@
;;; Code:
-
-(eval-when-compile
- (defmacro with-buffer-prepared-for-jit-lock (&rest body)
- "Execute BODY in current buffer, overriding several variables.
-Preserves the `buffer-modified-p' state of the current buffer."
- (declare (debug t))
- `(let ((inhibit-point-motion-hooks t))
- (with-silent-modifications
- ,@body))))
-
;;; Customization.
(defgroup jit-lock nil
@@ -328,7 +318,7 @@ like `debug-on-error' and Edebug can be used."
(when (buffer-live-p buffer)
(with-current-buffer buffer
;; (message "Jit-Debug %s" (buffer-name))
- (with-buffer-prepared-for-jit-lock
+ (with-silent-modifications
(let ((pos (point-min)))
(while
(progn
@@ -365,7 +355,7 @@ Only applies to the current buffer."
(defun jit-lock-refontify (&optional beg end)
"Force refontification of the region BEG..END (default whole buffer)."
- (with-buffer-prepared-for-jit-lock
+ (with-silent-modifications
(save-restriction
(widen)
(put-text-property (or beg (point-min)) (or end (point-max))
@@ -392,7 +382,7 @@ is active."
(push (current-buffer) jit-lock-defer-buffers))
;; Mark the area as defer-fontified so that the redisplay engine
;; is happy and so that the idle timer can find the places to fontify.
- (with-buffer-prepared-for-jit-lock
+ (with-silent-modifications
(put-text-property start
(next-single-property-change
start 'fontified nil
@@ -426,7 +416,7 @@ is active."
(defun jit-lock-fontify-now (&optional start end)
"Fontify current buffer from START to END.
Defaults to the whole buffer. END can be out of bounds."
- (with-buffer-prepared-for-jit-lock
+ (with-silent-modifications
(save-excursion
(unless start (setq start (point-min)))
(setq end (if end (min end (point-max)) (point-max)))
@@ -502,7 +492,7 @@ Defaults to the whole buffer. END can be out of bounds."
This applies to the buffer associated with marker START."
(when (marker-buffer start)
(with-current-buffer (marker-buffer start)
- (with-buffer-prepared-for-jit-lock
+ (with-silent-modifications
(when (> end (point-max))
(setq end (point-max) start (min start end)))
(when (< start (point-min))
@@ -616,7 +606,7 @@ non-nil in a repeated invocation of this function."
(when (buffer-live-p buffer)
(with-current-buffer buffer
;; (message "Jit-Defer %s" (buffer-name))
- (with-buffer-prepared-for-jit-lock
+ (with-silent-modifications
(let ((pos (point-min)))
(while
(progn
@@ -664,7 +654,7 @@ non-nil in a repeated invocation of this function."
jit-lock-context-unfontify-pos
'jit-lock-defer-multiline)
(point-min))))
- (with-buffer-prepared-for-jit-lock
+ (with-silent-modifications
;; Force contextual refontification.
(remove-text-properties
jit-lock-context-unfontify-pos (point-max)
@@ -695,7 +685,7 @@ will take place when text is fontified stealthily."
(when (and jit-lock-mode (not memory-full))
(let ((jit-lock-start start)
(jit-lock-end end))
- (with-buffer-prepared-for-jit-lock
+ (with-silent-modifications
(run-hook-with-args 'jit-lock-after-change-extend-region-functions
start end old-len)
;; Make sure we change at least one char (in case of deletions).
diff --git a/lisp/language/cyrillic.el b/lisp/language/cyrillic.el
index 4576373a6d1..a9017062cc6 100644
--- a/lisp/language/cyrillic.el
+++ b/lisp/language/cyrillic.el
@@ -131,13 +131,15 @@ Support for Russian using koi8-r and the russian-computer input method.")
:mime-charset 'koi8-u)
(set-language-info-alist
- "Ukrainian" '((charset koi8-u)
+ "Ukrainian" '((tutorial . "TUTORIAL.uk")
+ (charset koi8-u)
(coding-system koi8-u)
(coding-priority koi8-u)
(nonascii-translation . koi8-u)
(input-method . "ukrainian-computer")
+ (sample-text . "Ukrainian (Українська) Вітаю / Добрий день! / Привіт")
(documentation
- . "Support for Ukrainian with KOI8-U character set."))
+ . "Support for Ukrainian with koi8-u character set."))
'("Cyrillic"))
;;; ALTERNATIVNYJ stuff
@@ -254,14 +256,6 @@ Support for Russian using koi8-r and the russian-computer input method.")
\(The name Belarusian replaced Byelorussian in the early 1990s.)"))
'("Cyrillic"))
-(set-language-info-alist
- "Ukrainian" '((coding-system koi8-u)
- (coding-priority koi8-u)
- (input-method . "ukrainian-computer")
- (documentation
- . "Support for Ukrainian with koi8-u character set."))
- '("Cyrillic"))
-
(provide 'cyrillic)
;;; cyrillic.el ends here
diff --git a/lisp/language/ethio-util.el b/lisp/language/ethio-util.el
index a0159679da2..2f76acfe7cb 100644
--- a/lisp/language/ethio-util.el
+++ b/lisp/language/ethio-util.el
@@ -794,15 +794,15 @@ The 2nd and 3rd arguments BEGIN and END specify the region."
"This function is deprecated."
(interactive "*cInput number: 1. 2. 3. 4. 5.")
(cond
- ((= arg ?1)
+ ((eq arg ?1)
(insert ""))
- ((= arg ?2)
+ ((eq arg ?2)
(insert ""))
- ((= arg ?3)
+ ((eq arg ?3)
(insert ""))
- ((= arg ?4)
+ ((eq arg ?4)
(insert ""))
- ((= arg ?5)
+ ((eq arg ?5)
(insert ""))
(t
(error ""))))
@@ -816,7 +816,7 @@ The 2nd and 3rd arguments BEGIN and END specify the region."
"Convert each fidel characters in the current buffer into a fidel-tex command."
(interactive)
(let ((buffer-read-only nil)
- comp ch)
+ comp)
;; Special treatment for geminated characters.
;; Geminated characters la", etc. change into \geminateG{\laG}, etc.
@@ -835,21 +835,22 @@ The 2nd and 3rd arguments BEGIN and END specify the region."
;; Special Ethiopic punctuation.
(goto-char (point-min))
(while (re-search-forward "\\ce[».?]\\|«\\ce" nil t)
- (cond
- ((= (setq ch (preceding-char)) ?\»)
- (delete-char -1)
- (insert "\\rquoteG"))
- ((= ch ?.)
- (delete-char -1)
- (insert "\\dotG"))
- ((= ch ??)
- (delete-char -1)
- (insert "\\qmarkG"))
- (t
- (forward-char -1)
- (delete-char -1)
- (insert "\\lquoteG")
- (forward-char 1))))
+ (let ((ch (preceding-char)))
+ (cond
+ ((eq ch ?\»)
+ (delete-char -1)
+ (insert "\\rquoteG"))
+ ((eq ch ?.)
+ (delete-char -1)
+ (insert "\\dotG"))
+ ((eq ch ??)
+ (delete-char -1)
+ (insert "\\qmarkG"))
+ (t
+ (forward-char -1)
+ (delete-char -1)
+ (insert "\\lquoteG")
+ (forward-char 1)))))
;; Ethiopic characters to TeX macros
(robin-invert-region (point-min) (point-max) "ethiopic-tex")
diff --git a/lisp/language/indian.el b/lisp/language/indian.el
index 407173827fe..4994cfdc7ac 100644
--- a/lisp/language/indian.el
+++ b/lisp/language/indian.el
@@ -266,6 +266,27 @@ Meetei language and its script Meetei Mayek are supported in this
language environment."))
'("Indian"))
+(set-language-info-alist
+ "Wancho" '((charset unicode)
+ (coding-system utf-8)
+ (coding-priority utf-8)
+ (input-method . "wancho")
+ (sample-text . "Wancho (𞋒𞋀𞋉𞋃𞋕) 𞋂𞋈𞋛")
+ (documentation . "\
+Wancho language and its script are supported in this language
+environment."))
+ '("Indian"))
+
+(set-language-info-alist
+ "Toto" '((charset unicode)
+ (coding-system utf-8)
+ (coding-priority utf-8)
+ (input-method . "toto")
+ (documentation . "\
+Toto language using the Toto script is supported in this language
+environment."))
+ '("Indian"))
+
;; Replace mnemonic characters in REGEXP according to TABLE. TABLE is
;; an alist of (MNEMONIC-STRING . REPLACEMENT-STRING).
@@ -340,23 +361,24 @@ language environment."))
(defconst gurmukhi-composable-pattern
(let ((table
- '(("a" . "[\u0A01\u0A02\u0A70]") ; SIGN ADAK BINDI .. BINDI, TIPPI
+ '(("a" . "[\u0A01\u0A02\u0A70\u0A71\u0A75]") ; SIGN ADAK BINDI .. BINDI, TIPPI, ADDAK, YAKASH
("A" . "\u0A03") ; SIGN VISARGA
- ("V" . "[\u0A05-\u0A14]") ; independent vowel
+ ("V" . "[\u0A05-\u0A14\u0A72\u0A73]") ; independent vowel
("C" . "[\u0A15-\u0A39\u0A59-\u0A5E]") ; consonant
("Y" . "[\u0A2F\u0A30\u0A35\u0A39]") ; YA, RA, VA, HA
("n" . "\u0A3C") ; NUKTA
("v" . "[\u0A3E-\u0A4C]") ; vowel sign
("H" . "\u0A4D") ; VIRAMA
+ ("s" . "\u0A51") ; stress sign
("N" . "\u200C") ; ZWNJ
("J" . "\u200D") ; ZWJ
("X" . "[\u0A00-\u0A7F]")))) ; all coverage
(indian-compose-regexp
(concat
;; consonant-based syllables, or
- "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?\\|v*n?a?A?\\)\\|"
+ "Cn?\\(?:J?HJ?Cn?\\)*\\(?:H[NJ]?\\|v*n?a?s?v?A?\\)\\|"
;; syllables with an independent vowel, or
- "Vn?\\(?:J?HY\\)?v*n?a?A?\\|"
+ "Vn?\\(?:J?HY\\)?v*n?a?s?A?\\|"
;; special consonant form, or
"JHY\\|"
;; any other singleton characters
diff --git a/lisp/language/indonesian.el b/lisp/language/indonesian.el
index 699f8192543..5afcd27759d 100644
--- a/lisp/language/indonesian.el
+++ b/lisp/language/indonesian.el
@@ -34,7 +34,8 @@
(input-method . "balinese")
(sample-text . "Balinese (ᬅᬓ᭄ᬱᬭᬩᬮᬶ) ᬒᬁᬲ᭄ᬯᬲ᭄ᬢ᭄ᬬᬲ᭄ᬢᬸ")
(documentation . "\
-Balinese language and its script are supported in this language environment.")))
+Balinese language and its script are supported in this language environment."))
+ '("Indonesian"))
(set-language-info-alist
"Javanese" '((charset unicode)
@@ -43,7 +44,8 @@ Balinese language and its script are supported in this language environment.")))
(input-method . "javanese")
(sample-text . "Javanese (ꦲꦏ꧀ꦱꦫꦗꦮ) ꦲꦭꦺꦴ")
(documentation . "\
-Javanese language and its script are supported in this language environment.")))
+Javanese language and its script are supported in this language environment."))
+ '("Indonesian"))
(set-language-info-alist
"Sundanese" '((charset unicode)
@@ -52,7 +54,8 @@ Javanese language and its script are supported in this language environment.")))
(input-method . "sundanese")
(sample-text . "Sundanese (ᮃᮊ᮪ᮞᮛᮞᮥᮔ᮪ᮓ) ᮞᮙ᮪ᮕᮥᮛᮞᮥᮔ᮪")
(documentation . "\
-Sundanese language and its script are supported in this language environment.")))
+Sundanese language and its script are supported in this language environment."))
+ '("Indonesian"))
(set-language-info-alist
"Batak" '((charset unicode)
@@ -62,7 +65,8 @@ Sundanese language and its script are supported in this language environment."))
(sample-text . "Batak (ᯘᯮᯒᯗ᯲ᯅᯗᯂ᯲) ᯂᯬᯒᯘ᯲ / ᯔᯧᯐᯬᯀᯱᯐᯬᯀᯱ")
(documentation . "\
Languages that use the Batak script, such as Karo, Toba, Pakpak, Mandailing
-and Simalungun, are supported in this language environment.")))
+and Simalungun, are supported in this language environment."))
+ '("Indonesian"))
(set-language-info-alist
"Rejang" '((charset unicode)
@@ -71,7 +75,8 @@ and Simalungun, are supported in this language environment.")))
(input-method . "rejang")
(sample-text . "Rejang (ꥆꤰ꥓ꤼꤽ ꤽꥍꤺꥏ) ꤸꥉꥐꤺꥉꥂꥎ")
(documentation . "\
-Rejang language and its script are supported in this language environment.")))
+Rejang language and its script are supported in this language environment."))
+ '("Indonesian"))
(set-language-info-alist
"Makasar" '((charset unicode)
@@ -80,7 +85,8 @@ Rejang language and its script are supported in this language environment.")))
(input-method . "makasar")
(sample-text . "Makasar (𑻪𑻢𑻪𑻢) 𑻦𑻤𑻵𑻱")
(documentation . "\
-Makassarese language and its script Makasar are supported in this language environment.")))
+Makassarese language and its script Makasar are supported in this language environment."))
+ '("Indonesian"))
(set-language-info-alist
"Buginese" '((charset unicode)
@@ -89,7 +95,8 @@ Makassarese language and its script Makasar are supported in this language envir
(input-method . "lontara")
(sample-text . "Buginese (ᨒᨚᨈᨑ) ᨖᨒᨚ")
(documentation . "\
-Buginese language and its script Lontara are supported in this language environment.")))
+Buginese language and its script Lontara are supported in this language environment."))
+ '("Indonesian"))
;; Balinese composition rules
(let ((consonant "[\x1B13-\x1B33\x1B45-\x1B4B]")
diff --git a/lisp/language/lao.el b/lisp/language/lao.el
index 1861eff15eb..0ad5b9f84e3 100644
--- a/lisp/language/lao.el
+++ b/lisp/language/lao.el
@@ -60,9 +60,9 @@
(len (length chars))
;; Replace `c', `t', `v' to consonant, tone, and vowel.
(regexp (mapconcat (lambda (c)
- (cond ((= c ?c) consonant)
- ((= c ?t) tone)
- ((= c ?v) vowel-upper-lower)
+ (cond ((eq c ?c) consonant)
+ ((eq c ?t) tone)
+ ((eq c ?v) vowel-upper-lower)
(t (string c))))
(cdr l) ""))
;; Element of composition-function-table.
diff --git a/lisp/language/misc-lang.el b/lisp/language/misc-lang.el
index 3d5b68f84be..c34017d9b3a 100644
--- a/lisp/language/misc-lang.el
+++ b/lisp/language/misc-lang.el
@@ -228,7 +228,8 @@ thin (i.e. 1-dot width) space."
(sample-text . "Hanifi Rohingya (𐴌𐴟𐴇𐴥𐴝𐴚𐴒𐴙𐴝 𐴇𐴝𐴕𐴞𐴉𐴞 𐴓𐴠𐴑𐴤𐴝) 𐴀𐴝𐴏𐴓𐴝𐴀𐴡𐴤𐴛𐴝𐴓𐴝𐴙𐴑𐴟𐴔")
(documentation . "\
Rohingya language and its script Hanifi Rohingya are supported
-in this language environment.")))
+in this language environment."))
+ '("Misc"))
;; Hanifi Rohingya composition rules
(set-char-table-range
@@ -251,7 +252,8 @@ in this language environment.")))
(sample-text . "Kharoṣṭhī (𐨑𐨪𐨆𐨛𐨁) 𐨣𐨨𐨲𐨪𐨆 𐨐𐨪𐨅𐨨𐨁")
(documentation . "\
Language environment for Gāndhārī, Sanskrit, and other languages
-using the Kharoṣṭhī script.")))
+using the Kharoṣṭhī script."))
+ '("Misc"))
(let ((consonant "[\U00010A00\U00010A10-\U00010A35]")
(vowel "[\U00010A01-\U00010A06]")
@@ -269,6 +271,74 @@ using the Kharoṣṭhī script.")))
modifier "*")
1 'font-shape-gstring))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Adlam
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(set-language-info-alist
+ "Adlam" '((charset unicode)
+ (coding-system utf-8)
+ (coding-priority utf-8)
+ (input-method . "adlam")
+ (sample-text . "Adlam (𞤀𞤣𞤤𞤢𞤥) 𞤅𞤢𞤤𞤢𞥄𞤥")
+ (documentation . "\
+Fulani language and its script Adlam are supported
+in this language environment."))
+ '("Misc"))
+
+;; Adlam composition rules
+(set-char-table-range
+ composition-function-table
+ '(#x1E900 . #x1E95F)
+ (list (vector
+ "[\x1E900-\x1E95F]+"
+ 0 'font-shape-gstring)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Mende Kikakui
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(set-language-info-alist
+ "Mende Kikakui" '((charset unicode)
+ (coding-system utf-8)
+ (coding-priority utf-8)
+ (input-method . "mende-kikakui")
+ (sample-text . "Mende Kikakui (𞠀𞠁𞠂) 𞠛𞠉")
+ (documentation . "\
+Mende language and its script Kikakui are supported
+in this language environment."))
+ '("Misc"))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Gothic
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(set-language-info-alist
+ "Gothic" '((charset unicode)
+ (coding-system utf-8)
+ (coding-priority utf-8)
+ (input-method . "gothic")
+ (sample-text . "Gothic (𐌲𐌿𐍄𐌹𐍃𐌺𐌰) 𐌷𐌰𐌹𐌻𐍃 / 𐌷𐌰𐌹𐌻𐌰")
+ (documentation . "\
+Ancient Gothic language using the Gothic script is supported in this
+language environment."))
+ '("Misc"))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Coptic
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(set-language-info-alist
+ "Coptic" '((charset unicode)
+ (coding-system utf-8)
+ (coding-priority utf-8)
+ (input-method . "coptic")
+ (sample-text . "Coptic (ⲘⲉⲧⲢⲉⲙ̀ⲛⲭⲏⲙⲓ) Ⲛⲟⲩϥⲣⲓ")
+ (documentation . "\
+Coptic language using the Coptic script is supported in this
+language environment."))
+ '("Misc"))
+
(provide 'misc-lang)
;;; misc-lang.el ends here
diff --git a/lisp/language/philippine.el b/lisp/language/philippine.el
index e52ad6912cd..ce619bdaa1d 100644
--- a/lisp/language/philippine.el
+++ b/lisp/language/philippine.el
@@ -35,7 +35,8 @@
(sample-text . "Tagalog (ᜊᜌ᜔ᜊᜌᜒᜈ᜔) ᜃᜓᜋᜓᜐ᜔ᜆ")
(documentation . "\
Tagalog language using the Baybayin script is supported in
-this language environment.")))
+this language environment."))
+ '("Philippine"))
(set-language-info-alist
"Hanunoo" '((charset unicode)
@@ -44,7 +45,8 @@ this language environment.")))
(input-method . "hanunoo")
(sample-text . "Hanunoo (ᜱᜨᜳᜨᜳᜢ) ᜫᜬᜧ᜴ ᜣᜭᜯᜥ᜴ ᜰᜲᜭᜥ᜴")
(documentation . "\
-Philippine Language Hanunoo is supported in this language environment.")))
+Philippine Language Hanunoo is supported in this language environment."))
+ '("Philippine"))
(set-language-info-alist
"Buhid" '((charset unicode)
@@ -52,7 +54,8 @@ Philippine Language Hanunoo is supported in this language environment.")))
(coding-priority utf-8)
(input-method . "buhid")
(documentation . "\
-Philippine Language Buhid is supported in this language environment.")))
+Philippine Language Buhid is supported in this language environment."))
+ '("Philippine"))
(set-language-info-alist
"Tagbanwa" '((charset unicode)
@@ -61,7 +64,8 @@ Philippine Language Buhid is supported in this language environment.")))
(input-method . "tagbanwa")
(sample-text . "Tagbanwa (ᝦᝪᝯ) ᝫᝩᝬᝥ ᝣᝮᝧᝯ")
(documentation . "\
-Philippine Languages Tagbanwa are supported in this language environment.")))
+Philippine Languages Tagbanwa are supported in this language environment."))
+ '("Philippine"))
;; Tagalog composition rules
(let ((akshara "[\x1700-\x1711\x171F]")
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index b870494477c..517b23b1ea9 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -897,6 +897,15 @@ variable, and is meant to be used in `compilation-filter-hook'.")
(register-definition-prefixes "ansi-color" '("ansi-color-"))
+;;; Generated autoloads from ansi-osc.el
+
+(autoload 'ansi-osc-compilation-filter "ansi-osc" "\
+Maybe collect OSC control sequences.
+This function depends on the variable `ansi-osc-for-compilation-buffer',
+and is meant to be used in `compilation-filter-hook'.")
+(register-definition-prefixes "ansi-osc" '("ansi-osc-"))
+
+
;;; Generated autoloads from progmodes/antlr-mode.el
(push (purecopy '(antlr-mode 2 2 3)) package--builtin-versions)
@@ -4006,8 +4015,8 @@ from which to start.
(fn STRING &optional LAX FROM)")
(autoload 'describe-char-fold-equivalences "char-fold" "\
Display characters equivalent to CHAR under character-folding.
-Prompt for CHAR (using `read-char-by-name', which see for how can
-you specify the character). With no input, i.e. when CHAR is nil,
+Prompt for CHAR (using `read-char-by-name', which see for how to
+specify the character). With no input, i.e. when CHAR is nil,
describe all available character equivalences of `char-fold-to-regexp'.
Optional argument LAX (interactively, the prefix argument), if
non-nil, means also include partially matching ligatures and
@@ -4048,14 +4057,10 @@ Returns non-nil if any false statements are found.
(put 'checkdoc-force-history-flag 'safe-local-variable #'booleanp)
(put 'checkdoc-permit-comma-termination-flag 'safe-local-variable #'booleanp)
(put 'checkdoc-spellcheck-documentation-flag 'safe-local-variable #'booleanp)
-(put 'checkdoc-ispell-list-words 'safe-local-variable #'checkdoc-list-of-strings-p)
+(put 'checkdoc-ispell-list-words 'safe-local-variable #'list-of-strings-p)
(put 'checkdoc-arguments-in-order-flag 'safe-local-variable #'booleanp)
(put 'checkdoc-verb-check-experimental-flag 'safe-local-variable #'booleanp)
-(put 'checkdoc-symbol-words 'safe-local-variable #'checkdoc-list-of-strings-p)
-(autoload 'checkdoc-list-of-strings-p "checkdoc" "\
-Return t when OBJ is a list of strings.
-
-(fn OBJ)")
+(put 'checkdoc-symbol-words 'safe-local-variable #'list-of-strings-p)
(put 'checkdoc-proper-noun-regexp 'safe-local-variable 'stringp)
(put 'checkdoc-common-verbs-regexp 'safe-local-variable 'stringp)
(autoload 'checkdoc "checkdoc" "\
@@ -4316,79 +4321,6 @@ it is disabled.
;;; Generated autoloads from emacs-lisp/cl-generic.el
(push (purecopy '(cl-generic 1 0)) package--builtin-versions)
-(autoload 'cl-defgeneric "cl-generic" "\
-Create a generic function NAME.
-DOC-STRING is the base documentation for this class. A generic
-function has no body, as its purpose is to decide which method body
-is appropriate to use. Specific methods are defined with `cl-defmethod'.
-With this implementation the ARGS are currently ignored.
-OPTIONS-AND-METHODS currently understands:
-- (:documentation DOCSTRING)
-- (declare DECLARATIONS)
-- (:argument-precedence-order &rest ARGS)
-- (:method [QUALIFIERS...] ARGS &rest BODY)
-DEFAULT-BODY, if present, is used as the body of a default method.
-
-(fn NAME ARGS [DOC-STRING] [OPTIONS-AND-METHODS...] &rest DEFAULT-BODY)" nil t)
-(function-put 'cl-defgeneric 'lisp-indent-function 2)
-(function-put 'cl-defgeneric 'doc-string-elt 3)
-(autoload 'cl-generic-define "cl-generic" "\
-
-
-(fn NAME ARGS OPTIONS)")
-(autoload 'cl-defmethod "cl-generic" "\
-Define a new method for generic function NAME.
-This defines an implementation of NAME to use for invocations
-of specific types of arguments.
-
-ARGS is a list of dispatch arguments (see `cl-defun'), but where
-each variable element is either just a single variable name VAR,
-or a list on the form (VAR TYPE).
-
-For instance:
-
- (cl-defmethod foo (bar (format-string string) &optional zot)
- (format format-string bar))
-
-The dispatch arguments have to be among the mandatory arguments, and
-all methods of NAME have to use the same set of arguments for dispatch.
-Each dispatch argument and TYPE are specified in ARGS where the corresponding
-formal argument appears as (VAR TYPE) rather than just VAR.
-
-The optional EXTRA element, on the form `:extra STRING', allows
-you to add more methods for the same specializers and qualifiers.
-These are distinguished by STRING.
-
-The optional argument QUALIFIER is a specifier that modifies how
-the method is combined with other methods, including:
- :before - Method will be called before the primary
- :after - Method will be called after the primary
- :around - Method will be called around everything else
-The absence of QUALIFIER means this is a \"primary\" method.
-The set of acceptable qualifiers and their meaning is defined
-(and can be extended) by the methods of `cl-generic-combine-methods'.
-
-ARGS can also include so-called context specializers, introduced by
-`&context' (which should appear right after the mandatory arguments,
-before any &optional or &rest). They have the form (EXPR TYPE) where
-EXPR is an Elisp expression whose value should match TYPE for the
-method to be applicable.
-
-The set of acceptable TYPEs (also called \"specializers\") is defined
-(and can be extended) by the various methods of `cl-generic-generalizers'.
-
-(fn NAME [EXTRA] [QUALIFIER] ARGS &rest [DOCSTRING] BODY)" nil t)
-(function-put 'cl-defmethod 'doc-string-elt 'cl--defmethod-doc-pos)
-(function-put 'cl-defmethod 'lisp-indent-function 'defun)
-(autoload 'cl-generic-define-method "cl-generic" "\
-
-
-(fn NAME QUALIFIERS ARGS CALL-CON FUNCTION)")
-(autoload 'cl-find-method "cl-generic" "\
-
-
-(fn GENERIC QUALIFIERS SPECIALIZERS)")
-(register-definition-prefixes "cl-generic" '("cl-"))
;;; Generated autoloads from emacs-lisp/cl-indent.el
@@ -4476,8 +4408,6 @@ instead.
;;; Generated autoloads from emacs-lisp/cl-lib.el
(push (purecopy '(cl-lib 1 0)) package--builtin-versions)
-(define-obsolete-variable-alias 'custom-print-functions 'cl-custom-print-functions "\
-24.3")
(defvar cl-custom-print-functions nil "\
This is a list of functions that format user objects for printing.
Each function is called in turn with three arguments: the object, the
@@ -7256,6 +7186,13 @@ The mode's hook is called both when the mode is enabled and when
it is disabled.
(fn &optional ARG)" t)
+(defvar diff-add-log-use-relative-names nil "\
+Use relative file names when generating ChangeLog skeletons.
+The files will be relative to the root directory of the VC
+repository. This option affects the behavior of
+`diff-add-log-current-defuns'.")
+(custom-autoload 'diff-add-log-use-relative-names "diff-mode" t)
+(put 'diff-add-log-use-relative-names 'safe-local-variable #'booleanp)
(autoload 'diff-vc-deduce-fileset "diff-mode")
(register-definition-prefixes "diff-mode" '("diff-"))
@@ -7585,6 +7522,34 @@ This provides increased compatibility for users who call this function
in `.emacs'.
(fn ARG)")
+(autoload 'standard-display-by-replacement-char "disp-table" "\
+Produce code to display characters between FROM and TO using REPL.
+This function produces a buffer with code to set up `standard-display-table'
+such that characters that cannot be displayed by the terminal, and
+don't already have their display set up in `standard-display-table', will
+be represented by a replacement character. You can evaluate the produced
+code to use the setup for the current Emacs session, or copy the code
+into your init file, to make Emacs use it for subsequent sessions.
+
+Interactively, the produced code arranges for any character in
+the range [#x100..#x10FFFF] that the terminal cannot display to
+be represented by the #xFFFD Unicode replacement character.
+
+When called from Lisp, FROM and TO define the range of characters for
+which to produce the setup code for `standard-display-table'. If they
+are omitted, they default to #x100 and #x10FFFF respectively, covering
+the entire non-ASCII range of Unicode characters.
+REPL is the replacement character to use. If it's omitted, it defaults
+to #xFFFD, the Unicode replacement character, usually displayed as a
+black diamond with a question mark inside.
+The produced code sets up `standard-display-table' to show REPL with
+the `homoglyph' face, making the replacements stand out on display.
+
+This command is most useful with text-mode terminals, such as the
+Linux console, for which Emacs has a reliable way of determining
+which characters can be displayed and which cannot.
+
+(fn &optional REPL FROM TO)" t)
(register-definition-prefixes "disp-table" '("display-table-print-array"))
@@ -7844,7 +7809,7 @@ Document types are symbols like `dvi', `ps', `pdf', `epub',
Major mode in DocView buffers.
DocView Mode is an Emacs document viewer. It displays PDF, PS
-and DVI files (as PNG images) in Emacs buffers.
+and DVI files (as PNG or SVG images) in Emacs buffers.
You can use \\<doc-view-mode-map>\\[doc-view-toggle-display] to
toggle between displaying the document or editing it as text.
@@ -8079,6 +8044,7 @@ Valid keywords and arguments are:
`nodigits' to suppress digits as prefix arguments.
(fn BS &optional NAME M ARGS)")
+(make-obsolete 'easy-mmode-define-keymap 'define-keymap "29.1")
(autoload 'easy-mmode-defmap "easy-mmode" "\
Define a constant M whose value is the result of `easy-mmode-define-keymap'.
The M, BS, and ARGS arguments are as per that function. DOC is
@@ -8089,6 +8055,7 @@ This macro is deprecated; use `defvar-keymap' instead.
(fn M BS DOC &rest ARGS)" nil t)
(function-put 'easy-mmode-defmap 'doc-string-elt 3)
(function-put 'easy-mmode-defmap 'lisp-indent-function 1)
+(make-obsolete 'easy-mmode-defmap 'defvar-keymap "29.1")
(autoload 'easy-mmode-defsyntax "easy-mmode" "\
Define variable ST as a syntax-table.
CSS contains a list of syntax specifications of the form (CHAR . SYNTAX).
@@ -9458,6 +9425,8 @@ Already submitted bugs can be found in the Emacs bug tracker:
(fn TOPIC &optional UNUSED)" t)
(set-advertised-calling-convention 'report-emacs-bug '(topic) '"24.5")
+(autoload 'emacs-build-description "emacsbug" "\
+Insert a description of the current Emacs build in the current buffer." t)
(autoload 'submit-emacs-patch "emacsbug" "\
Send an Emacs patch to the Emacs maintainers.
Interactively, you will be prompted for SUBJECT and a patch FILE
@@ -9465,7 +9434,7 @@ name (which will be attached to the mail). You will end up in a
Message buffer where you can explain more about the patch.
(fn SUBJECT FILE)" t)
-(register-definition-prefixes "emacsbug" '("emacs-bug--system-description" "report-emacs-bug-"))
+(register-definition-prefixes "emacsbug" '("report-emacs-bug-"))
;;; Generated autoloads from vc/emerge.el
@@ -12122,13 +12091,18 @@ Define some key bindings for the `find-function' family of functions.")
;;; Generated autoloads from find-lisp.el
(autoload 'find-lisp-find-dired "find-lisp" "\
-Find files in DIR, matching REGEXP.
+Find the files within DIR whose names match REGEXP.
+A Dired buffer with the results will be opened.
(fn DIR REGEXP)" t)
(autoload 'find-lisp-find-dired-subdirectories "find-lisp" "\
Find all subdirectories of DIR.
(fn DIR)" t)
+(autoload 'find-lisp-find-dired-subdirs-other-window "find-lisp" "\
+Same as `find-lisp-find-dired-subdirectories', but use another window.
+
+(fn DIR)" t)
(autoload 'find-lisp-find-dired-filter "find-lisp" "\
Change the filter on a `find-lisp-find-dired' buffer to REGEXP.
@@ -12586,6 +12560,18 @@ value associated with ?b in SPECIFICATION, either padding it with
leading zeros or truncating leading characters until it's ten
characters wide\".
+the substitution for a specification character can also be a
+function, taking no arguments and returning a string to be used
+for the replacement. It will only be called if FORMAT uses that
+character. For example:
+
+ (format-spec \"%n\"
+ \\=`((?n . ,(lambda ()
+ (read-number \"Number: \")))))
+
+Note that it is best to make sure the function is not quoted,
+like above, so that it is compiled by the byte-compiler.
+
Any text properties of FORMAT are copied to the result, with any
text properties of a %-spec itself copied to its substitution.
@@ -15411,7 +15397,7 @@ it is disabled.
;;; Generated autoloads from progmodes/hideshow.el
-(defvar hs-special-modes-alist (mapcar 'purecopy '((c-mode "{" "}" "/[*/]" nil nil) (c++-mode "{" "}" "/[*/]" nil nil) (bibtex-mode ("@\\S(*\\(\\s(\\)" 1)) (java-mode "{" "}" "/[*/]" nil nil) (js-mode "{" "}" "/[*/]" nil) (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil))) "\
+(defvar hs-special-modes-alist (mapcar #'purecopy '((c-mode "{" "}" "/[*/]" nil nil) (c++-mode "{" "}" "/[*/]" nil nil) (bibtex-mode ("@\\S(*\\(\\s(\\)" 1)) (java-mode "{" "}" "/[*/]" nil nil) (js-mode "{" "}" "/[*/]" nil) (mhtml-mode "{\\|<[^/>]*?" "}\\|</[^/>]*[^/]>" "<!--" mhtml-forward nil))) "\
Alist for initializing the hideshow variables for different modes.
Each element has the form
(MODE START END COMMENT-START FORWARD-SEXP-FUNC ADJUST-BEG-FUNC
@@ -16758,8 +16744,9 @@ and that image type is present in `image-type-auto-detectable' with a
non-nil value. If that value is non-nil, but not t, then the image type
must be available.")
(autoload 'create-image "image" "\
-Create an image.
-FILE-OR-DATA is an image file name or image data.
+Create an image from FILE-OR-DATA.
+FILE-OR-DATA is an image file name or image data. If it is a relative
+file name, the function will look for it along `image-load-path'.
Optional TYPE is a symbol describing the image type. If TYPE is omitted
or nil, try to determine the image type from its first few bytes
@@ -16778,10 +16765,6 @@ Value is the image created, or nil if images of type TYPE are not supported.
Images should not be larger than specified by `max-image-size'.
-Image file names that are not absolute are searched for in the
-\"images\" sub-directory of `data-directory' and
-`x-bitmap-file-path' (in that order).
-
(fn FILE-OR-DATA &optional TYPE DATA-P &rest PROPS)")
(autoload 'put-image "image" "\
Put image IMAGE in front of POS in the current buffer.
@@ -16916,17 +16899,39 @@ should output the image in the current buffer, converted to
(register-definition-prefixes "image-converter" '("image-convert"))
-;;; Generated autoloads from image-dired.el
+;;; Generated autoloads from image/image-crop.el
-(push (purecopy '(image-dired 0 4 11)) package--builtin-versions)
-(autoload 'image-dired-dired-toggle-marked-thumbs "image-dired" "\
-Toggle thumbnails in front of file names in the Dired buffer.
-If no marked file could be found, insert or hide thumbnails on the
-current line. ARG, if non-nil, specifies the files to use instead
-of the marked files. If ARG is an integer, use the next ARG (or
-previous -ARG, if ARG<0) files.
+(autoload 'image-cut "image-crop" "\
+Cut a rectangle from the image under point, filling it with COLOR.
+COLOR defaults to the value of `image-cut-color'.
+Interactively, with prefix argument, prompt for COLOR to use.
-(fn &optional ARG)" t)
+(fn &optional COLOR)" t)
+(autoload 'image-crop "image-crop" "\
+Crop the image under point.
+If CUT is non-nil, remove a rectangle from the image instead of
+cropping the image. In that case CUT should be the name of a
+color to fill the rectangle.
+
+While cropping the image, the following key bindings are available:
+
+`q': Exit without changing anything.
+`RET': Crop/cut the image.
+`m': Make mouse movements move the rectangle instead of altering the
+ rectangle shape.
+`s': Same as `m', but make the rectangle into a square first.
+
+After cropping an image, you can save it by `M-x image-save' or
+\\<image-map>\\[image-save] when point is over the image.
+
+(fn &optional CUT)" t)
+(register-definition-prefixes "image-crop" '("image-c"))
+
+
+;;; Generated autoloads from image/image-dired.el
+
+(push (purecopy '(image-dired 0 5)) package--builtin-versions)
+(put 'image-dired-thumbnail-storage 'safe-local-variable (lambda (x) (eq x 'per-directory)))
(autoload 'image-dired-dired-with-window-configuration "image-dired" "\
Open directory DIR and create a default window configuration.
@@ -16967,11 +16972,11 @@ used or not. If non-nil, use `display-buffer' instead of
`image-dired-previous-line-and-display' where we do not want the
thumbnail buffer to be selected.
-(fn &optional ARG APPEND DO-NOT-POP)" t)
+(fn &optional ARG APPEND DO-NOT-POP)" '(nil dired-mode))
(autoload 'image-dired-show-all-from-dir "image-dired" "\
Make a thumbnail buffer for all images in DIR and display it.
-Any file matching `image-file-name-regexp' is considered an image
-file.
+Any file matching `image-dired--file-name-regexp' is considered an
+image file.
If the number of image files in DIR exceeds
`image-dired-show-all-from-dir-max-files', ask for confirmation
@@ -16980,22 +16985,52 @@ never ask for confirmation.
(fn DIR)" t)
(defalias 'image-dired 'image-dired-show-all-from-dir)
-(autoload 'image-dired-tag-files "image-dired" "\
-Tag marked file(s) in Dired. With prefix ARG, tag file at point.
+(autoload 'image-dired-bookmark-jump "image-dired" "\
+Default bookmark handler for Image-Dired buffers.
-(fn ARG)" t)
-(autoload 'image-dired-delete-tag "image-dired" "\
-Remove tag for selected file(s).
-With prefix argument ARG, remove tag from file at point.
+(fn BOOKMARK)")
+(define-obsolete-function-alias 'tumme #'image-dired "24.4")
+(define-obsolete-function-alias 'image-dired-setup-dired-keybindings #'image-dired-minor-mode "26.1")
+(register-definition-prefixes "image-dired" '("image-dired-"))
-(fn ARG)" t)
-(autoload 'image-dired-jump-thumbnail-buffer "image-dired" "\
-Jump to thumbnail buffer." t)
-(autoload 'image-dired-minor-mode "image-dired" "\
-Setup easy-to-use keybindings for the commands to be used in Dired mode.
+
+;;; Generated autoloads from image/image-dired-dired.el
+
+(autoload 'image-dired-dired-toggle-marked-thumbs "image-dired-dired" "\
+Toggle thumbnails in front of file names in the Dired buffer.
+If no marked file could be found, insert or hide thumbnails on the
+current line. ARG, if non-nil, specifies the files to use instead
+of the marked files. If ARG is an integer, use the next ARG (or
+previous -ARG, if ARG<0) files.
-Note that n, p and <down> and <up> will be hijacked and bound to
-`image-dired-dired-next-line' and `image-dired-dired-previous-line'.
+(fn &optional ARG)" '(dired-mode))
+(autoload 'image-dired-jump-thumbnail-buffer "image-dired-dired" "\
+Jump to thumbnail buffer." '(dired-mode))
+(autoload 'image-dired-minor-mode "image-dired-dired" "\
+Setup easy-to-use keybindings for Image-Dired in Dired mode.
+
+This minor mode adds these additional bindings:
+\\<image-dired-minor-mode-map>
+ \\[image-dired-next-line-and-display] Move to next line and display thumbnail image.
+ \\[image-dired-previous-line-and-display] Move to previous line and display thumbnail image.
+ \\[image-dired-mark-and-display-next] Mark current file and display next thumbnail image.
+ \\[image-dired-jump-thumbnail-buffer] Jump to thumbnail buffer.
+
+For reference, these are the default Image-Dired bindings that
+are always available in Dired:
+\\<dired-mode-map>
+ \\[image-dired-display-thumbs] Display thumbnails of all marked files.
+ \\[image-dired-tag-files] Tag marked file(s).
+ \\[image-dired-delete-tag] Remove tag for selected file(s).
+ \\[image-dired-jump-thumbnail-buffer] Jump to thumbnail buffer.
+ \\[image-dired-dired-display-image] Display current image file.
+ \\[image-dired-dired-display-external] Display file at point using an external viewer.
+ \\[image-dired-display-thumbs-append] Append thumbnails to thumbnail buffer.
+ \\[image-dired-display-thumb] Display thumbnails of all marked files.
+ \\[image-dired-dired-comment-files] Add comment to current or marked files in Dired.
+ \\[image-dired-mark-tagged-files] Use REGEXP to mark files with matching tag.
+ \\[image-dired-dired-toggle-marked-thumbs] Toggle thumbnails in front of file names.
+ \\[image-dired-dired-edit-comment-and-tags] Edit comment and tags of marked images.
This is a minor mode. If called interactively, toggle the
`Image-Dired minor mode' mode. If the prefix argument is
@@ -17013,21 +17048,19 @@ The mode's hook is called both when the mode is enabled and when
it is disabled.
(fn &optional ARG)" t)
-(autoload 'image-dired-display-thumbs-append "image-dired" "\
-Append thumbnails to `image-dired-thumbnail-buffer'." t)
-(autoload 'image-dired-display-thumb "image-dired" "\
-Shorthand for `image-dired-display-thumbs' with prefix argument." t)
-(autoload 'image-dired-dired-display-external "image-dired" "\
-Display file at point using an external viewer." t)
-(autoload 'image-dired-dired-display-image "image-dired" "\
+(autoload 'image-dired-display-thumbs-append "image-dired-dired" "\
+Append thumbnails to `image-dired-thumbnail-buffer'." '(dired-mode))
+(autoload 'image-dired-display-thumb "image-dired-dired" "\
+Shorthand for `image-dired-display-thumbs' with prefix argument." '(dired-mode))
+(autoload 'image-dired-dired-display-external "image-dired-dired" "\
+Display file at point using an external viewer." '(dired-mode))
+(autoload 'image-dired-dired-display-image "image-dired-dired" "\
Display current image file.
See documentation for `image-dired-display-image' for more information.
-With prefix argument ARG, display image in its original size.
-(fn &optional ARG)" t)
-(autoload 'image-dired-dired-comment-files "image-dired" "\
-Add comment to current or marked files in Dired." t)
-(autoload 'image-dired-mark-tagged-files "image-dired" "\
+(fn &optional _)" '(dired-mode))
+(set-advertised-calling-convention 'image-dired-dired-display-image 'nil '"29.1")
+(autoload 'image-dired-mark-tagged-files "image-dired-dired" "\
Use REGEXP to mark files with matching tag.
A `tag' is a keyword, a piece of meta data, associated with an
image file and stored in image-dired's database file. This command
@@ -17035,18 +17068,38 @@ lets you input a regexp and this will be matched against all tags
on all image files in the database file. The files that have a
matching tag will be marked in the Dired buffer.
-(fn REGEXP)" t)
-(autoload 'image-dired-dired-edit-comment-and-tags "image-dired" "\
+(fn REGEXP)" '(dired-mode))
+(register-definition-prefixes "image-dired-dired" '("image-dired-"))
+
+
+;;; Generated autoloads from image/image-dired-external.el
+
+(register-definition-prefixes "image-dired-external" '("image-dired-"))
+
+
+;;; Generated autoloads from image/image-dired-tags.el
+
+(autoload 'image-dired-tag-files "image-dired-tags" "\
+Tag marked file(s) in Dired. With prefix ARG, tag file at point.
+
+(fn ARG)" '(dired-mode))
+(autoload 'image-dired-delete-tag "image-dired-tags" "\
+Remove tag for selected file(s).
+With prefix argument ARG, remove tag from file at point.
+
+(fn ARG)" '(dired-mode))
+(autoload 'image-dired-dired-comment-files "image-dired-tags" "\
+Add comment to current or marked files in Dired." '(dired-mode))
+(autoload 'image-dired-dired-edit-comment-and-tags "image-dired-tags" "\
Edit comment and tags of current or marked image files.
Edit comment and tags for all marked image files in an
-easy-to-use form." t)
-(autoload 'image-dired-bookmark-jump "image-dired" "\
-Default bookmark handler for Image-Dired buffers.
+easy-to-use form." '(dired-mode))
+(register-definition-prefixes "image-dired-tags" '("image-dired-"))
-(fn BOOKMARK)")
-(define-obsolete-function-alias 'tumme #'image-dired "24.4")
-(define-obsolete-function-alias 'image-dired-setup-dired-keybindings #'image-dired-minor-mode "26.1")
-(register-definition-prefixes "image-dired" '("image-dired-"))
+
+;;; Generated autoloads from image/image-dired-util.el
+
+(register-definition-prefixes "image-dired-util" '("image-dired-"))
;;; Generated autoloads from image-file.el
@@ -17224,6 +17277,11 @@ an index alist of the current buffer. The function is
called within a `save-excursion'.
See `imenu--index-alist' for the format of the buffer index alist.")
+(defvar-local imenu-submenus-on-top t "\
+Flag specifying whether items with sublists should be kept at top.
+
+For some indexes, such as those describing sections in a document, it
+makes sense to keep their original order even in the menubar.")
(defvar-local imenu-prev-index-position-function 'beginning-of-defun "\
Function for finding the next index position.
@@ -18488,7 +18546,7 @@ This option also treats some characters in the `mule-unicode-...'
charsets if you don't have a Unicode font with which to display them.
Setting this variable directly does not take effect;
-use either \\[customize] or the function `latin1-display'.")
+use either \\[customize] or the command `latin1-display'.")
(custom-autoload 'latin1-display "latin1-disp" nil)
(autoload 'latin1-display "latin1-disp" "\
Set up Latin-1/ASCII display for the arguments character SETS.
@@ -18504,7 +18562,7 @@ This uses the transliterations of the Lynx browser. The display isn't
changed if the display can render Unicode characters.
Setting this variable directly does not take effect;
-use either \\[customize] or the function `latin1-display'.")
+use either \\[customize] or the command `latin1-display-ucs-per-lynx'.")
(custom-autoload 'latin1-display-ucs-per-lynx "latin1-disp" nil)
(autoload 'latin1-display-ucs-per-lynx "latin1-disp" "\
Set up Latin-1/ASCII display for Unicode characters.
@@ -18616,58 +18674,6 @@ sleep in seconds.
(register-definition-prefixes "life" '("life-"))
-;;; Generated autoloads from linum.el
-
-(autoload 'linum-mode "linum" "\
-Toggle display of line numbers in the left margin (Linum mode).
-
-This mode has been largely replaced by `display-line-numbers-mode'
-(which is much faster and has fewer interaction problems with other
-modes).
-
-Linum mode is a buffer-local minor mode.
-
-This is a minor mode. If called interactively, toggle the `Linum
-mode' mode. If the prefix argument is positive, enable the mode,
-and if it is zero or negative, disable the mode.
-
-If called from Lisp, toggle the mode if ARG is `toggle'. Enable
-the mode if ARG is nil, omitted, or is a positive number.
-Disable the mode if ARG is a negative number.
-
-To check whether the minor mode is enabled in the current buffer,
-evaluate `linum-mode'.
-
-The mode's hook is called both when the mode is enabled and when
-it is disabled.
-
-(fn &optional ARG)" t)
-(put 'global-linum-mode 'globalized-minor-mode t)
-(defvar global-linum-mode nil "\
-Non-nil if Global Linum mode is enabled.
-See the `global-linum-mode' command
-for a description of this minor mode.
-Setting this variable directly does not take effect;
-either customize it (see the info node `Easy Customization')
-or call the function `global-linum-mode'.")
-(custom-autoload 'global-linum-mode "linum" nil)
-(autoload 'global-linum-mode "linum" "\
-Toggle Linum mode in all buffers.
-With prefix ARG, enable Global Linum mode if ARG is positive;
-otherwise, disable it.
-
-If called from Lisp, toggle the mode if ARG is `toggle'.
-Enable the mode if ARG is nil, omitted, or is a positive number.
-Disable the mode if ARG is a negative number.
-
-Linum mode is enabled in all buffers where `linum-on' would do it.
-
-See `linum-mode' for more information on Linum mode.
-
-(fn &optional ARG)" t)
-(register-definition-prefixes "linum" '("linum-"))
-
-
;;; Generated autoloads from cedet/ede/linux.el
(register-definition-prefixes "ede/linux" '("ede-linux-" "project-linux-"))
@@ -18688,7 +18694,7 @@ See `linum-mode' for more information on Linum mode.
(put 'generated-autoload-file 'safe-local-variable 'stringp)
(put 'generated-autoload-load-name 'safe-local-variable 'stringp)
(autoload 'loaddefs-generate "loaddefs-gen" "\
-Generate loaddefs files for Lisp files in the directories DIRS.
+Generate loaddefs files for Lisp files in one or more directories given by DIR.
DIR can be either a single directory or a list of directories.
The autoloads will be written to OUTPUT-FILE. If any Lisp file
@@ -18696,7 +18702,7 @@ binds `generated-autoload-file' as a file-local variable, write
its autoloads into the specified file instead.
The function does NOT recursively descend into subdirectories of the
-directory or directories specified by DIRS.
+directories specified by DIR.
Optional argument EXCLUDED-FILES, if non-nil, should be a list of
files, such as preloaded files, whose autoloads should not be written
@@ -18841,6 +18847,8 @@ done. Otherwise, this function will use the current buffer.
Major mode for browsing CVS log output.
(fn)" t)
+(autoload 'log-view-get-marked "log-view" "\
+Return the list of tags for the marked log entries.")
(register-definition-prefixes "log-view" '("log-view-"))
@@ -20916,6 +20924,11 @@ it is disabled.
(register-definition-prefixes "mwheel" '("mouse-wheel-" "mwheel-"))
+;;; Generated autoloads from emacs-lisp/nadvice.el
+
+(push (purecopy '(nadvice 1 0)) package--builtin-versions)
+
+
;;; Generated autoloads from net/net-utils.el
(autoload 'ifconfig "net-utils" "\
@@ -21908,7 +21921,7 @@ Coloring:
;;; Generated autoloads from org/org.el
-(push (purecopy '(org 9 5 4)) package--builtin-versions)
+(push (purecopy '(org 9 5 5)) package--builtin-versions)
(autoload 'org-babel-do-load-languages "org" "\
Load the languages defined in `org-babel-load-languages'.
@@ -23214,6 +23227,13 @@ Completion rules for the `cvs' command.")
(register-definition-prefixes "pcmpl-cvs" '("pcmpl-cvs-"))
+;;; Generated autoloads from pcmpl-git.el
+
+(autoload 'pcomplete/git "pcmpl-git" "\
+Completion for the `git' command.")
+(register-definition-prefixes "pcmpl-git" '("pcmpl-git--"))
+
+
;;; Generated autoloads from pcmpl-gnu.el
(autoload 'pcomplete/gzip "pcmpl-gnu" "\
@@ -23226,7 +23246,16 @@ Completion for GNU `make'.")
Completion for the GNU tar utility.")
(autoload 'pcomplete/find "pcmpl-gnu" "\
Completion for the GNU find utility.")
-(defalias 'pcomplete/gdb 'pcomplete/xargs)
+(autoload 'pcomplete/awk "pcmpl-gnu" "\
+Completion for the `awk' command.")
+(autoload 'pcomplete/gpg "pcmpl-gnu" "\
+Completion for the `gpg` command.")
+(autoload 'pcomplete/gdb "pcmpl-gnu" "\
+Completion for the `gdb' command.")
+(autoload 'pcomplete/emacs "pcmpl-gnu" "\
+Completion for the `emacs' command.")
+(autoload 'pcomplete/emacsclient "pcmpl-gnu" "\
+Completion for the `emacsclient' command.")
(register-definition-prefixes "pcmpl-gnu" '("pcmpl-gnu-" "pcomplete/find"))
@@ -23238,6 +23267,10 @@ Completion for GNU/Linux `kill', using /proc filesystem.")
Completion for GNU/Linux `umount'.")
(autoload 'pcomplete/mount "pcmpl-linux" "\
Completion for GNU/Linux `mount'.")
+(autoload 'pcomplete/systemctl "pcmpl-linux" "\
+Completion for the `systemctl' command.")
+(autoload 'pcomplete/journalctl "pcmpl-linux" "\
+Completion for the `journalctl' command.")
(register-definition-prefixes "pcmpl-linux" '("pcmpl-linux-" "pcomplete-pare-list"))
@@ -23245,6 +23278,8 @@ Completion for GNU/Linux `mount'.")
(autoload 'pcomplete/rpm "pcmpl-rpm" "\
Completion for the `rpm' command.")
+(autoload 'pcomplete/dnf "pcmpl-rpm" "\
+Completion for the `dnf' command.")
(register-definition-prefixes "pcmpl-rpm" '("pcmpl-rpm-"))
@@ -23256,16 +23291,174 @@ Completion for `cd'.")
(autoload 'pcomplete/rmdir "pcmpl-unix" "\
Completion for `rmdir'.")
(autoload 'pcomplete/rm "pcmpl-unix" "\
-Completion for `rm'.")
+Completion for the `rm' command.")
(autoload 'pcomplete/xargs "pcmpl-unix" "\
Completion for `xargs'.")
-(defalias 'pcomplete/time 'pcomplete/xargs)
+(autoload 'pcomplete/time "pcmpl-unix" "\
+Completion for the `time' command.")
(autoload 'pcomplete/which "pcmpl-unix" "\
Completion for `which'.")
+(autoload 'pcomplete/cat "pcmpl-unix" "\
+Completion for the `cat' command.")
+(autoload 'pcomplete/tac "pcmpl-unix" "\
+Completion for the `tac' command.")
+(autoload 'pcomplete/nl "pcmpl-unix" "\
+Completion for the `nl' command.")
+(autoload 'pcomplete/od "pcmpl-unix" "\
+Completion for the `od' command.")
+(autoload 'pcomplete/base32 "pcmpl-unix" "\
+Completion for the `base32' and `base64' commands.")
+(defalias 'pcomplete/base64 'pcomplete/base32)
+(autoload 'pcomplete/basenc "pcmpl-unix" "\
+Completion for the `basenc' command.")
+(autoload 'pcomplete/fmt "pcmpl-unix" "\
+Completion for the `fmt' command.")
+(autoload 'pcomplete/pr "pcmpl-unix" "\
+Completion for the `pr' command.")
+(autoload 'pcomplete/fold "pcmpl-unix" "\
+Completion for the `fold' command.")
+(autoload 'pcomplete/head "pcmpl-unix" "\
+Completion for the `head' command.")
+(autoload 'pcomplete/tail "pcmpl-unix" "\
+Completion for the `tail' command.")
+(autoload 'pcomplete/split "pcmpl-unix" "\
+Completion for the `split' command.")
+(autoload 'pcomplete/csplit "pcmpl-unix" "\
+Completion for the `csplit' command.")
+(autoload 'pcomplete/wc "pcmpl-unix" "\
+Completion for the `wc' command.")
+(autoload 'pcomplete/sum "pcmpl-unix" "\
+Completion for the `sum' command.")
+(autoload 'pcomplete/cksum "pcmpl-unix" "\
+Completion for the `cksum' command.")
+(autoload 'pcomplete/b2sum "pcmpl-unix" "\
+Completion for the `b2sum' command.")
+(autoload 'pcomplete/md5sum "pcmpl-unix" "\
+Completion for checksum commands.")
+(defalias 'pcomplete/sha1sum 'pcomplete/md5sum)
+(defalias 'pcomplete/sha224sum 'pcomplete/md5sum)
+(defalias 'pcomplete/sha256sum 'pcomplete/md5sum)
+(defalias 'pcomplete/sha384sum 'pcomplete/md5sum)
+(defalias 'pcomplete/sha521sum 'pcomplete/md5sum)
+(autoload 'pcomplete/sort "pcmpl-unix" "\
+Completion for the `sort' command.")
+(autoload 'pcomplete/shuf "pcmpl-unix" "\
+Completion for the `shuf' command.")
+(autoload 'pcomplete/uniq "pcmpl-unix" "\
+Completion for the `uniq' command.")
+(autoload 'pcomplete/comm "pcmpl-unix" "\
+Completion for the `comm' command.")
+(autoload 'pcomplete/ptx "pcmpl-unix" "\
+Completion for the `ptx' command.")
+(autoload 'pcomplete/tsort "pcmpl-unix" "\
+Completion for the `tsort' command.")
+(autoload 'pcomplete/cut "pcmpl-unix" "\
+Completion for the `cut' command.")
+(autoload 'pcomplete/paste "pcmpl-unix" "\
+Completion for the `paste' command.")
+(autoload 'pcomplete/join "pcmpl-unix" "\
+Completion for the `join' command.")
+(autoload 'pcomplete/tr "pcmpl-unix" "\
+Completion for the `tr' command.")
+(autoload 'pcomplete/expand "pcmpl-unix" "\
+Completion for the `expand' command.")
+(autoload 'pcomplete/unexpand "pcmpl-unix" "\
+Completion for the `unexpand' command.")
+(autoload 'pcomplete/ls "pcmpl-unix" "\
+Completion for the `ls' command.")
+(defalias 'pcomplete/dir 'pcomplete/ls)
+(defalias 'pcomplete/vdir 'pcomplete/ls)
+(autoload 'pcomplete/cp "pcmpl-unix" "\
+Completion for the `cp' command.")
+(autoload 'pcomplete/dd "pcmpl-unix" "\
+Completion for the `dd' command.")
+(autoload 'pcomplete/install "pcmpl-unix" "\
+Completion for the `install' command.")
+(autoload 'pcomplete/mv "pcmpl-unix" "\
+Completion for the `mv' command.")
+(autoload 'pcomplete/shred "pcmpl-unix" "\
+Completion for the `shred' command.")
+(autoload 'pcomplete/ln "pcmpl-unix" "\
+Completion for the `ln' command.")
+(autoload 'pcomplete/mkdir "pcmpl-unix" "\
+Completion for the `mkdir' command.")
+(autoload 'pcomplete/mkfifo "pcmpl-unix" "\
+Completion for the `mkfifo' command.")
+(autoload 'pcomplete/mknod "pcmpl-unix" "\
+Completion for the `mknod' command.")
+(autoload 'pcomplete/readlink "pcmpl-unix" "\
+Completion for the `readlink' command.")
(autoload 'pcomplete/chown "pcmpl-unix" "\
Completion for the `chown' command.")
(autoload 'pcomplete/chgrp "pcmpl-unix" "\
Completion for the `chgrp' command.")
+(autoload 'pcomplete/chmod "pcmpl-unix" "\
+Completion for the `chmod' command.")
+(autoload 'pcomplete/touch "pcmpl-unix" "\
+Completion for the `touch' command.")
+(autoload 'pcomplete/df "pcmpl-unix" "\
+Completion for the `df' command.")
+(autoload 'pcomplete/du "pcmpl-unix" "\
+Completion for the `du' command.")
+(autoload 'pcomplete/stat "pcmpl-unix" "\
+Completion for the `stat' command.")
+(autoload 'pcomplete/sync "pcmpl-unix" "\
+Completion for the `sync' command.")
+(autoload 'pcomplete/truncate "pcmpl-unix" "\
+Completion for the `truncate' command.")
+(autoload 'pcomplete/echo "pcmpl-unix" "\
+Completion for the `echo' command.")
+(autoload 'pcomplete/test "pcmpl-unix" "\
+Completion for the `test' command.")
+(defalias (intern "pcomplete/[") 'pcomplete/test)
+(autoload 'pcomplete/tee "pcmpl-unix" "\
+Completion for the `tee' command.")
+(autoload 'pcomplete/basename "pcmpl-unix" "\
+Completion for the `basename' command.")
+(autoload 'pcomplete/dirname "pcmpl-unix" "\
+Completion for the `dirname' command.")
+(autoload 'pcomplete/pathchk "pcmpl-unix" "\
+Completion for the `pathchk' command.")
+(autoload 'pcomplete/mktemp "pcmpl-unix" "\
+Completion for the `mktemp' command.")
+(autoload 'pcomplete/realpath "pcmpl-unix" "\
+Completion for the `realpath' command.")
+(autoload 'pcomplete/id "pcmpl-unix" "\
+Completion for the `id' command.")
+(autoload 'pcomplete/groups "pcmpl-unix" "\
+Completion for the `groups' command.")
+(autoload 'pcomplete/who "pcmpl-unix" "\
+Completion for the `who' command.")
+(autoload 'pcomplete/date "pcmpl-unix" "\
+Completion for the `date' command.")
+(autoload 'pcomplete/nproc "pcmpl-unix" "\
+Completion for the `nproc' command.")
+(autoload 'pcomplete/uname "pcmpl-unix" "\
+Completion for the `uname' command.")
+(autoload 'pcomplete/hostname "pcmpl-unix" "\
+Completion for the `hostname' command.")
+(autoload 'pcomplete/uptime "pcmpl-unix" "\
+Completion for the `uptime' command.")
+(autoload 'pcomplete/chcon "pcmpl-unix" "\
+Completion for the `chcon' command.")
+(autoload 'pcomplete/runcon "pcmpl-unix" "\
+Completion for the `runcon' command.")
+(autoload 'pcomplete/chroot "pcmpl-unix" "\
+Completion for the `chroot' command.")
+(autoload 'pcomplete/env "pcmpl-unix" "\
+Completion for the `env' command.")
+(autoload 'pcomplete/nice "pcmpl-unix" "\
+Completion for the `nice' command.")
+(autoload 'pcomplete/nohup "pcmpl-unix" "\
+Completion for the `nohup' command.")
+(autoload 'pcomplete/stdbuf "pcmpl-unix" "\
+Completion for the `stdbuf' command.")
+(autoload 'pcomplete/timeout "pcmpl-unix" "\
+Completion for the `timeout' command.")
+(autoload 'pcomplete/numfmt "pcmpl-unix" "\
+Completion for the `numfmt' command.")
+(autoload 'pcomplete/seq "pcmpl-unix" "\
+Completion for the `seq' command.")
(autoload 'pcomplete/ssh "pcmpl-unix" "\
Completion rules for the `ssh' command.")
(defalias 'pcomplete/rsh #'pcomplete/ssh)
@@ -23273,13 +23466,25 @@ Completion rules for the `ssh' command.")
Completion rules for the `scp' command.
Includes files as well as host names followed by a colon.")
(autoload 'pcomplete/telnet "pcmpl-unix")
+(autoload 'pcomplete/sudo "pcmpl-unix" "\
+Completion for the `sudo' command.")
(register-definition-prefixes "pcmpl-unix" '("pcmpl-" "pcomplete/"))
;;; Generated autoloads from pcmpl-x.el
+(autoload 'pcomplete/tex "pcmpl-x" "\
+Completion for the `tex' command.")
+(defalias 'pcomplete/pdftex 'pcomplete/tex)
+(defalias 'pcomplete/latex 'pcomplete/tex)
+(defalias 'pcomplete/pdflatex 'pcomplete/tex)
+(autoload 'pcomplete/luatex "pcmpl-x" "\
+Completion for the `luatex' command.")
+(defalias 'pcomplete/lualatex 'pcomplete/luatex)
(autoload 'pcomplete/tlmgr "pcmpl-x" "\
Completion for the `tlmgr' command.")
+(autoload 'pcomplete/rg "pcmpl-x" "\
+Completion for the `rg' command.")
(autoload 'pcomplete/ack "pcmpl-x" "\
Completion for the `ack' command.
Start an argument with `-' to complete short options and `--' for
@@ -23290,6 +23495,8 @@ Completion for the `ag' command.")
(autoload 'pcomplete/bcc32 "pcmpl-x" "\
Completion function for Borland's C++ compiler.")
(defalias 'pcomplete/bcc 'pcomplete/bcc32)
+(autoload 'pcomplete/rclone "pcmpl-x" "\
+Completion for the `rclone' command.")
(register-definition-prefixes "pcmpl-x" '("pcmpl-x-"))
@@ -24329,7 +24536,7 @@ Open profile FILENAME.
;;; Generated autoloads from progmodes/project.el
-(push (purecopy '(project 0 8 1)) package--builtin-versions)
+(push (purecopy '(project 0 8 2)) package--builtin-versions)
(autoload 'project-current "project" "\
Return the project instance in DIRECTORY, defaulting to `default-directory'.
@@ -24827,8 +25034,8 @@ Run an inferior Python process.
Argument CMD defaults to `python-shell-calculate-command' return
value. When called interactively with `prefix-arg', it allows
the user to edit such value and choose whether the interpreter
-should be DEDICATED for the current buffer. When numeric prefix
-arg is other than 0 or 4 do not SHOW.
+should be DEDICATED to the current buffer or project. When
+numeric prefix arg is other than 0 or 4 do not SHOW.
For a given buffer and same values of DEDICATED, if a process is
already running for it, it will do nothing. This means that if
@@ -24840,6 +25047,37 @@ Runs the hook `inferior-python-mode-hook' after
process buffer for a list of commands.)
(fn &optional CMD DEDICATED SHOW)" t)
+(autoload 'python-add-import "python" "\
+Add an import statement to the current buffer.
+
+Interactively, ask for an import statement using all imports
+found in the current project as suggestions. With a prefix
+argument, restrict the suggestions to imports defining the symbol
+at point. If there is only one such suggestion, act without
+asking.
+
+When calling from Lisp, use a non-nil NAME to restrict the
+suggestions to imports defining NAME.
+
+(fn NAME)" t)
+(autoload 'python-import-symbol-at-point "python" "\
+Add an import statement for the symbol at point to the current buffer.
+This works like `python-add-import', but with the opposite
+behavior regarding the prefix argument." t)
+(autoload 'python-remove-import "python" "\
+Remove an import statement from the current buffer.
+
+Interactively, ask for an import statement to remove, displaying
+the imports of the current buffer as suggestions. With a prefix
+argument, restrict the suggestions to imports defining the symbol
+at point. If there is only one such suggestion, act without
+asking.
+
+(fn NAME)" t)
+(autoload 'python-sort-imports "python" "\
+Sort Python imports in the current buffer." t)
+(autoload 'python-fix-imports "python" "\
+Add missing imports and remove unused ones from the current buffer." t)
(autoload 'python-mode "python" "\
Major mode for editing Python files.
@@ -25690,6 +25928,9 @@ The mode's hook is called both when the mode is enabled and when
it is disabled.
(fn &optional ARG)" t)
+(autoload 'repeat-exit "repeat" "\
+Exit the repeating sequence.
+This function can be used to force exit of repetition while it's active." t)
(register-definition-prefixes "repeat" '("describe-repeat-maps" "repeat-"))
@@ -25897,7 +26138,7 @@ Regexp to match Header fields that Rmail should display.
If nil, display all header fields except those matched by
`rmail-ignored-headers'.")
(custom-autoload 'rmail-displayed-headers "rmail" t)
-(defvar rmail-retry-ignored-headers (purecopy "^x-authentication-warning:\\|^x-detected-operating-system:\\|^x-spam[-a-z]*:\\|content-type:\\|content-transfer-encoding:\\|mime-version:\\|message-id:") "\
+(defvar rmail-retry-ignored-headers (concat "^x-authentication-warning:\\|^x-detected-operating-system:\\|" "^x-spam[-a-z]*:\\|^arc-.*:\\|" "^content-type:\\|^content-transfer-encoding:\\|" "^mime-version:\\|^message-id:\\|^x-google-smtp-source:\\|" "^x-received:\\|^received-spf:\\|" "^authentication-results:\\|^dkim-signature:") "\
Headers that should be stripped when retrying a failed message.")
(custom-autoload 'rmail-retry-ignored-headers "rmail" t)
(defvar rmail-highlighted-headers (purecopy "^From:\\|^Subject:") "\
@@ -29200,6 +29441,8 @@ PROMPT will be inserted at the start of the buffer, but won't be
included in the resulting string. If PROMPT is nil, no help text
will be inserted.
+Also see `read-string-from-buffer'.
+
(fn PROMPT STRING SUCCESS-CALLBACK &key ABORT-CALLBACK)")
(autoload 'read-string-from-buffer "string-edit" "\
Switch to a new buffer to edit STRING in a recursive edit.
@@ -29209,6 +29452,8 @@ PROMPT will be inserted at the start of the buffer, but won't be
included in the resulting string. If nil, no prompt will be
inserted in the buffer.
+Also see `string-edit'.
+
(fn PROMPT STRING)")
(register-definition-prefixes "string-edit" '("string-edit-"))
@@ -29334,6 +29579,10 @@ Studlify-case the current buffer." t)
;;; Generated autoloads from emacs-lisp/subr-x.el
+(defsubst string-join (strings &optional separator) "\
+Join all STRINGS using SEPARATOR.
+Optional argument SEPARATOR must be a string, a vector, or a list of
+characters; nil stands for the empty string." (mapconcat #'identity strings separator))
(autoload 'string-truncate-left "subr-x" "\
If STRING is longer than LENGTH, return a truncated version.
When truncating, \"...\" is always prepended to the string, so
@@ -30538,9 +30787,9 @@ such as if there are no commands in the file, the value of `tex-default-mode'
says which mode to use.
(fn)" t)
-(defalias 'TeX-mode #'tex-mode)
-(defalias 'plain-TeX-mode #'plain-tex-mode)
-(defalias 'LaTeX-mode #'latex-mode)
+ (defalias 'TeX-mode #'tex-mode)
+ (defalias 'plain-TeX-mode #'plain-tex-mode)
+ (defalias 'LaTeX-mode #'latex-mode)
(autoload 'plain-tex-mode "tex-mode" "\
Major mode for editing files of input for plain TeX.
Makes $ and } display the characters they match.
@@ -30961,28 +31210,6 @@ Display a list of threads." t)
(register-definition-prefixes "thread" '("thread-list-"))
-;;; Generated autoloads from thumbs.el
-
-(autoload 'thumbs-find-thumb "thumbs" "\
-Display the thumbnail for IMG.
-
-(fn IMG)" t)
-(autoload 'thumbs-show-from-dir "thumbs" "\
-Make a preview buffer for all images in DIR.
-Optional argument REG to select file matching a regexp,
-and SAME-WINDOW to show thumbs in the same window.
-
-(fn DIR &optional REG SAME-WINDOW)" t)
-(autoload 'thumbs-dired-show-marked "thumbs" "\
-In dired, make a thumbs buffer with marked files." t)
-(autoload 'thumbs-dired-show "thumbs" "\
-In dired, make a thumbs buffer with all files in current directory." t)
-(defalias 'thumbs 'thumbs-show-from-dir)
-(autoload 'thumbs-dired-setroot "thumbs" "\
-In dired, call the setroot program on the image at point." t)
-(register-definition-prefixes "thumbs" '("thumbs-"))
-
-
;;; Generated autoloads from emacs-lisp/thunk.el
(push (purecopy '(thunk 1 0)) package--builtin-versions)
@@ -31755,7 +31982,7 @@ It must be supported by libarchive(3).")
List of suffixes which indicate a compressed file.
It must be supported by libarchive(3).")
(defmacro tramp-archive-autoload-file-name-regexp nil "\
-Regular expression matching archive file names." '(rx bos (group (+ nonl) "." (regexp (regexp-opt tramp-archive-suffixes)) (32 "." (regexp (regexp-opt tramp-archive-compression-suffixes)))) (group "/" (* nonl)) eos))
+Regular expression matching archive file names." `(rx bos (group (+ nonl) "." ,(cons '| tramp-archive-suffixes) (32 "." ,(cons '| tramp-archive-compression-suffixes))) (group "/" (* nonl)) eos))
(autoload 'tramp-archive-file-name-handler "tramp-archive")
(defun tramp-archive-autoload-file-name-handler (operation &rest args) "\
Load Tramp archive file name handler, and perform OPERATION." (defvar tramp-archive-autoload) (let ((default-directory temporary-file-directory) (tramp-archive-autoload tramp-archive-enabled)) (apply #'tramp-autoload-file-name-handler operation args)))
@@ -31778,9 +32005,15 @@ Add archive file name handler to `file-name-handler-alist'." (when (and tramp-ar
;;; Generated autoloads from net/tramp-compat.el
+ (defalias 'tramp-compat-rx #'rx)
(register-definition-prefixes "tramp-compat" '("tramp-"))
+;;; Generated autoloads from net/tramp-container.el
+
+(register-definition-prefixes "tramp-container" '("tramp-"))
+
+
;;; Generated autoloads from net/tramp-crypt.el
(register-definition-prefixes "tramp-crypt" '("tramp-crypt-"))
@@ -32516,6 +32749,10 @@ if it had been inserted from a file named URL.
(fn URL &optional VISIT BEG END REPLACE)")
+(autoload 'url-insert-file-contents-literally "url-handlers" "\
+Insert the data retrieved from URL literally in the current buffer.
+
+(fn URL)")
(register-definition-prefixes "url-handlers" '("url-"))
@@ -32593,14 +32830,14 @@ Fetch a GNU Info URL.
(fn URL)")
-(defalias 'url-rlogin 'url-generic-emulator-loader)
+(define-obsolete-function-alias 'url-rlogin #'url-generic-emulator-loader "29.1")
(defalias 'url-telnet 'url-generic-emulator-loader)
(defalias 'url-tn3270 'url-generic-emulator-loader)
(autoload 'url-data "url-misc" "\
Fetch a data URL (RFC 2397).
(fn URL)")
-(register-definition-prefixes "url-misc" '("url-do-terminal-emulator"))
+(register-definition-prefixes "url-misc" '("url-"))
;;; Generated autoloads from url/url-news.el
@@ -33161,6 +33398,12 @@ given, the tag is made as a new branch and the files are
checked out in that new branch.
(fn DIR NAME BRANCHP)" t)
+(autoload 'vc-create-branch "vc" "\
+Descending recursively from DIR, make a branch called NAME.
+After a new branch is made, the files are checked out in that new branch.
+Uses `vc-create-tag' with the non-nil arg `branchp'.
+
+(fn DIR NAME)" t)
(autoload 'vc-retrieve-tag "vc" "\
For each file in or below DIR, retrieve their tagged version NAME.
NAME can name a branch, in which case this command will switch to the
@@ -33171,8 +33414,16 @@ If NAME is empty, it refers to the latest revisions of the current branch.
If locking is used for the files in DIR, then there must not be any
locked files at or below DIR (but if NAME is empty, locked files are
allowed and simply skipped).
+If the prefix argument BRANCHP is given, switch the branch
+and check out the files in that branch.
This function runs the hook `vc-retrieve-tag-hook' when finished.
+(fn DIR NAME &optional BRANCHP)" t)
+(autoload 'vc-switch-branch "vc" "\
+Switch to the branch NAME in the directory DIR.
+If NAME is empty, it refers to the latest revisions of the current branch.
+Uses `vc-retrieve-tag' with the non-nil arg `branchp'.
+
(fn DIR NAME)" t)
(autoload 'vc-print-log "vc" "\
List the change log of the current fileset in a window.
@@ -33202,11 +33453,13 @@ Show the change log for BRANCH root in a window.
(autoload 'vc-log-incoming "vc" "\
Show log of changes that will be received with pull from REMOTE-LOCATION.
When called interactively with a prefix argument, prompt for REMOTE-LOCATION.
+In some version control systems REMOTE-LOCATION can be a remote branch name.
(fn &optional REMOTE-LOCATION)" t)
(autoload 'vc-log-outgoing "vc" "\
Show log of changes that will be sent with a push operation to REMOTE-LOCATION.
When called interactively with a prefix argument, prompt for REMOTE-LOCATION.
+In some version control systems REMOTE-LOCATION can be a remote branch name.
(fn &optional REMOTE-LOCATION)" t)
(autoload 'vc-log-search "vc" "\
@@ -33265,6 +33518,22 @@ On a non-distributed version control system, this signals an error.
It also signals an error in a Bazaar bound branch.
(fn &optional ARG)" t)
+(autoload 'vc-pull-and-push "vc" "\
+First pull, and then push the current branch.
+The push will only be performed if the pull operation was successful.
+
+You must be visiting a version controlled file, or in a `vc-dir' buffer.
+
+On a distributed version control system, this runs a \"pull\"
+operation on the current branch, prompting for the precise
+command if required. Optional prefix ARG non-nil forces a prompt
+for the VCS command to run. If this is successful, a \"push\"
+operation will then be done.
+
+On a non-distributed version control system, this signals an error.
+It also signals an error in a Bazaar bound branch.
+
+(fn &optional ARG)" t)
(autoload 'vc-switch-backend "vc" "\
Make BACKEND the current version control system for FILE.
FILE must already be registered in BACKEND. The change is not
@@ -33313,6 +33582,22 @@ From a program, any ARGS are assumed to be filenames for which
log entries should be gathered.
(fn &rest ARGS)" t)
+(autoload 'vc-edit-next-command "vc" "\
+Request editing the next VC shell command before execution.
+This is a prefix command. It affects only a VC command executed
+immediately after this one." t)
+(autoload 'vc-prepare-patch "vc" "\
+Compose an Email sending patches for REVISIONS to ADDRESSEE.
+If `vc-prepare-patches-separately' is nil, SUBJECT will be used
+as the default subject for the message (and it will be prompted
+for when called interactively). Otherwise a separate message
+will be composed for each revision, with SUBJECT derived from the
+invidividual commits.
+
+When invoked interactively in a Log View buffer with marked
+revisions, those revisions will be used.
+
+(fn ADDRESSEE SUBJECT REVISIONS)" t)
(register-definition-prefixes "vc" '("vc-" "with-vc-properties"))
@@ -33432,6 +33717,7 @@ FILE-OR-LIST is the name of a working file; it may be a list of
files or be nil (to execute commands that don't expect a file
name or set of files). If an optional list of FLAGS is present,
that is inserted into the command line before the filename.
+
Return the return value of the slave command in the synchronous
case, and the process object in the asynchronous case.
@@ -33446,6 +33732,7 @@ case, and the process object in the asynchronous case.
;;; Generated autoloads from vc/vc-git.el
+(put 'vc-git-annotate-switches 'safe-local-variable (lambda (switches) (equal switches "-w")))
(defun vc-git-registered (file)
"Return non-nil if FILE is registered with git."
(if (vc-find-root file ".git") ; Short cut.
@@ -34305,10 +34592,6 @@ Convert Vietnamese characters of the current buffer to `VIQR' mnemonics." t)
;;; Generated autoloads from view.el
-(defvar view-remove-frame-by-deleting t "\
-Determine how View mode removes a frame no longer needed.
-If nil, make an icon of the frame. If non-nil, delete the frame.")
-(custom-autoload 'view-remove-frame-by-deleting "view" t)
(defvar-local view-mode nil "\
Non-nil if View mode is enabled.
Don't change this variable directly, you must change it by one of the
@@ -34605,6 +34888,24 @@ Turn on Viper emulation of Vi in Emacs. See Info node `(viper)Top'." t)
(register-definition-prefixes "w32-vars" '("w32-"))
+;;; Generated autoloads from image/wallpaper.el
+
+(put 'wallpaper-setter-create 'lisp-indent-function 1)
+(autoload 'wallpaper-set "wallpaper" "\
+Set the desktop background to FILE in a graphical environment.
+
+On GNU/Linux and other Unix-like systems, this relies on an
+external command. Which command to use is automatically detected
+in most cases, but can be manually customized with the user
+options `wallpaper-command' and `wallpaper-command-args'.
+
+On MS-Windows and Haiku systems, no external command is needed,
+so the value of `wallpaper-commands' is ignored.
+
+(fn FILE)" t)
+(register-definition-prefixes "wallpaper" '("wallpaper-"))
+
+
;;; Generated autoloads from emacs-lisp/warnings.el
(defvar warning-prefix-function nil "\
@@ -35636,7 +35937,7 @@ If LIMIT is non-nil, then do not consider characters beyond LIMIT.
;;; Generated autoloads from progmodes/xref.el
-(push (purecopy '(xref 1 5 0)) package--builtin-versions)
+(push (purecopy '(xref 1 5 1)) package--builtin-versions)
(autoload 'xref-find-backend "xref")
(define-obsolete-function-alias 'xref-pop-marker-stack #'xref-go-back "29.1")
(autoload 'xref-go-back "xref" "\
@@ -35844,7 +36145,13 @@ Extract file name from an yenc header.")
;;; Generated autoloads from play/zone.el
(autoload 'zone "zone" "\
-Zone out, completely." t)
+Zone out, completely.
+With a prefix argument the user is prompted for a program to run.
+When called from Lisp the optional argument PGM can be used to
+run a specific program. The program must be a member of
+`zone-programs'.
+
+(fn &optional PGM)" t)
(register-definition-prefixes "zone" '("zone-"))
;;; End of scraped data
@@ -35855,6 +36162,7 @@ Zone out, completely." t)
;; no-byte-compile: t
;; version-control: never
;; no-update-autoloads: t
+;; no-native-compile: t
;; coding: utf-8-emacs-unix
;; End:
diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el
index 431d8369c1e..048e16e8d80 100644
--- a/lisp/leim/quail/indian.el
+++ b/lisp/leim/quail/indian.el
@@ -2134,5 +2134,119 @@ is."
("`m" ?ꫲ)
("`?" ?꫱))
+(quail-define-package
+ "wancho" "Wancho" "𞋒" t "Wancho phonetic input method.
+
+ `\\=`' is used to switch levels instead of Alt-Gr."
+ nil t t t t nil nil nil nil nil t)
+
+(quail-define-rules
+ ("``" ?𞋿)
+ ("1" ?𞋱)
+ ("`1" ?1)
+ ("2" ?𞋲)
+ ("`2" ?2)
+ ("3" ?𞋳)
+ ("`3" ?3)
+ ("4" ?𞋴)
+ ("`4" ?4)
+ ("5" ?𞋵)
+ ("`5" ?5)
+ ("6" ?𞋶)
+ ("`6" ?6)
+ ("7" ?𞋷)
+ ("`7" ?7)
+ ("8" ?𞋸)
+ ("`8" ?8)
+ ("9" ?𞋹)
+ ("`9" ?9)
+ ("0" ?𞋰)
+ ("`0" ?0)
+ ("q" ?𞋠)
+ ("Q" ?𞋡)
+ ("w" ?𞋒)
+ ("e" ?𞋛)
+ ("E" ?𞋧)
+ ("r" ?𞋗)
+ ("t" ?𞋋)
+ ("T" ?𞋌)
+ ("y" ?𞋆)
+ ("Y" ?𞋫)
+ ("u" ?𞋞)
+ ("U" ?𞋪)
+ ("i" ?𞋜)
+ ("I" ?𞋥)
+ ("o" ?𞋕)
+ ("O" ?𞋖)
+ ("`o" ?𞋢)
+ ("`O" ?𞋦)
+ ("p" ?𞋊)
+ ("P" ?𞋇)
+ ("a" ?𞋁)
+ ("A" ?𞋀)
+ ("`a" ?𞋤)
+ ("`A" ?𞋣)
+ ("s" ?𞋎)
+ ("S" ?𞋏)
+ ("d" ?𞋄)
+ ("f" ?𞋍)
+ ("g" ?𞋅)
+ ("h" ?𞋚)
+ ("j" ?𞋐)
+ ("k" ?𞋔)
+ ("K" ?𞋙)
+ ("l" ?𞋈)
+ ("L" ?𞋟)
+ ("z" ?𞋑)
+ ("x" ?𞋩)
+ ("X" ?𞋝)
+ ("c" ?𞋃)
+ ("C" ?𞋬)
+ ("v" ?𞋓)
+ ("V" ?𞋭)
+ ("b" ?𞋂)
+ ("B" ?𞋮)
+ ("n" ?𞋉)
+ ("N" ?𞋯)
+ ("m" ?𞋘)
+ ("M" ?𞋨))
+
+(quail-define-package
+ "toto" "Toto" "𞊒𞊪" nil "Toto script phonetic input method."
+ nil t t t t nil nil nil nil nil t)
+
+(quail-define-rules
+ ("q" ?𞊫)
+ ("Q" ?𞊬)
+ ("w" ?𞊜)
+ ("e" ?𞊦)
+ ("E" ?𞊧)
+ ("r" ?𞊟)
+ ("t" ?𞊒)
+ ("y" ?𞊛)
+ ("u" ?𞊥)
+ ("i" ?𞊡)
+ ("I" ?𞊢)
+ ("o" ?𞊪)
+ ("p" ?𞊐)
+ ("a" ?𞊭)
+ ("s" ?𞊙)
+ ("d" ?𞊓)
+ ("f" ?𞊮)
+ ("g" ?𞊕)
+ ("h" ?𞊞)
+ ("j" ?𞊝)
+ ("k" ?𞊔)
+ ("l" ?𞊠)
+ ("z" ?𞊣)
+ ("Z" ?𞊤)
+ ("x" ?𞊨)
+ ("X" ?𞊩)
+ ("c" ?𞊚)
+ ("b" ?𞊑)
+ ("n" ?𞊗)
+ ("N" ?𞊘)
+ ("m" ?𞊖))
+
(provide 'indian)
;;; indian.el ends here
diff --git a/lisp/leim/quail/misc-lang.el b/lisp/leim/quail/misc-lang.el
index 0c4a0d4ce40..73287ee7842 100644
--- a/lisp/leim/quail/misc-lang.el
+++ b/lisp/leim/quail/misc-lang.el
@@ -1180,5 +1180,500 @@
(".||" ?𐩗)
(".=" ?𐩘))
+(quail-define-package
+ "adlam" "Adlam" "𞤀" t "Adlam input method.
+
+ `\\=`' is used to switch levels instead of Alt-Gr.
+" nil t t t t nil nil nil nil nil t)
+
+(quail-define-rules
+ ("1" ?𞥑)
+ ("`!" ?𞥞)
+ ("2" ?𞥒)
+ ("3" ?𞥓)
+ ("4" ?𞥔)
+ ("5" ?𞥕)
+ ("6" ?𞥖)
+ ("7" ?𞥗)
+ ("8" ?𞥘)
+ ("9" ?𞥙)
+ ("0" ?𞥐)
+ ("q" ?𞤹)
+ ("Q" ?𞤗)
+ ("`q" ?𞥆)
+ ("w" ?𞤱)
+ ("W" ?𞤏)
+ ("`w" ?𞥈)
+ ("`W" ?𞥉)
+ ("e" ?𞤫)
+ ("E" ?𞤉)
+ ("`e" ?𞥅)
+ ("r" ?𞤪)
+ ("R" ?𞤈)
+ ("t" ?𞤼)
+ ("T" ?𞤚)
+ ("y" ?𞤴)
+ ("Y" ?𞤒)
+ ("`y" ?𞤰)
+ ("`Y" ?𞤎)
+ ("u" ?𞤵)
+ ("U" ?𞤓)
+ ("i" ?𞤭)
+ ("I" ?𞤋)
+ ("o" ?𞤮)
+ ("O" ?𞤌)
+ ("p" ?𞤨)
+ ("P" ?𞤆)
+ ("a" ?𞤢)
+ ("A" ?𞤀)
+ ("`a" ?𞥄)
+ ("s" ?𞤧)
+ ("S" ?𞤅)
+ ("`s" ?𞥃)
+ ("`S" ?𞤡)
+ ("d" ?𞤣)
+ ("D" ?𞤁)
+ ("`d" ?𞤯)
+ ("`D" ?𞤍)
+ ("f" ?𞤬)
+ ("F" ?𞤊)
+ ("g" ?𞤺)
+ ("G" ?𞤘)
+ ("`g" ?𞥀)
+ ("`G" ?𞤞)
+ ("h" ?𞤸)
+ ("H" ?𞤖)
+ ("`h" ?𞥇)
+ ("j" ?𞤶)
+ ("J" ?𞤔)
+ ("k" ?𞤳)
+ ("K" ?𞤑)
+ ("`k" ?𞤿)
+ ("`K" ?𞤝)
+ ("l" ?𞤤)
+ ("L" ?𞤂)
+ ("z" ?𞥁)
+ ("Z" ?𞤟)
+ ("`z" ?𞥂)
+ ("`Z" ?𞤠)
+ ("x" ?𞤽)
+ ("X" ?𞤛)
+ ("c" ?𞤷)
+ ("C" ?𞤕)
+ ("`c" #x200C) ; ZWNJ
+ ("v" ?𞤾)
+ ("V" ?𞤜)
+ ("`v" ?𞥊)
+ ("b" ?𞤦)
+ ("B" ?𞤄)
+ ("`b" ?𞤩)
+ ("`B" ?𞤇)
+ ("n" ?𞤲)
+ ("N" ?𞤐)
+ ("`n" ?𞤻)
+ ("`N" ?𞤙)
+ ("m" ?𞤥)
+ ("M" ?𞤃)
+ ("`m" ?𞥋)
+ ("`/" ?𞥟))
+
+(quail-define-package
+ "mende-kikakui" "Mende Kikakui" "𞠗" nil
+ "Mende Kikakui input method." nil t t t t nil nil nil nil nil t)
+
+(quail-define-rules
+ ("1" ?𞣇)
+ ("2" ?𞣈)
+ ("3" ?𞣉)
+ ("4" ?𞣊)
+ ("5" ?𞣋)
+ ("6" ?𞣌)
+ ("7" ?𞣍)
+ ("8" ?𞣎)
+ ("9" ?𞣏)
+
+ (".1" ?𞣐)
+ (".2" ?𞣑)
+ (".3" ?𞣒)
+ (".4" ?𞣓)
+ (".5" ?𞣔)
+ (".6" ?𞣕)
+ (".7" ?𞣖)
+
+ ("ki" ?𞠀)
+ ("ka" ?𞠁)
+ ("ku" ?𞠂)
+ ("kee" ?𞠃)
+ ("ke" ?𞠄)
+ ("koo" ?𞠅)
+ ("ko" ?𞠆)
+ ("kua" ?𞠇)
+
+ ("wi" ?𞠈)
+ ("wa" ?𞠉)
+ ("wu" ?𞠊)
+ ("wee" ?𞠋)
+ ("we" ?𞠌)
+ ("woo" ?𞠍)
+ ("wo" ?𞠎)
+ ("wui" ?𞠏)
+ ("wei" ?𞠐)
+
+ ("wvi" ?𞠑)
+ ("wua" ?𞠒)
+ ("wve" ?𞠓)
+
+ ("min" ?𞠔)
+ ("man" ?𞠕)
+ ("mun" ?𞠖)
+ ("men" ?𞠗)
+ ("mon" ?𞠘)
+ ("muan" ?𞠙)
+ ("muen" ?𞠚)
+
+ ("bi" ?𞠛)
+ ("ba" ?𞠜)
+ ("bu" ?𞠝)
+ ("bee" ?𞠞)
+ ("be" ?𞠟)
+ ("boo" ?𞠠)
+ ("bo" ?𞠡)
+
+ ("i" ?𞠢)
+ ("a" ?𞠣)
+ ("u" ?𞠤)
+ ("ee" ?𞠥)
+ ("e" ?𞠦)
+ ("oo" ?𞠧)
+ ("o" ?𞠨)
+ ("ei" ?𞠩)
+ ("in" ?𞠪)
+ ("inn" ?𞠫)
+ ("an" ?𞠬)
+ ("en" ?𞠭)
+
+ ("si" ?𞠮)
+ ("sa" ?𞠯)
+ ("su" ?𞠰)
+ ("see" ?𞠱)
+ ("se" ?𞠲)
+ ("soo" ?𞠳)
+ ("so" ?𞠴)
+ ("sia" ?𞠵)
+
+ ("li" ?𞠶)
+ ("la" ?𞠷)
+ ("lu" ?𞠸)
+ ("lee" ?𞠹)
+ ("le" ?𞠺)
+ ("loo" ?𞠻)
+ ("lo" ?𞠼)
+ ("lle" ?𞠽)
+
+ ("di" ?𞠾)
+ ("da" ?𞠿)
+ ("du" ?𞡀)
+ ("dee" ?𞡁)
+ ("doo" ?𞡂)
+ ("do" ?𞡃)
+
+ ("ti" ?𞡄)
+ ("ta" ?𞡅)
+ ("tu" ?𞡆)
+ ("tee" ?𞡇)
+ ("te" ?𞡈)
+ ("too" ?𞡉)
+ ("to" ?𞡊)
+
+ ("ji" ?𞡋)
+ ("ja" ?𞡌)
+ ("ju" ?𞡍)
+ ("jee" ?𞡎)
+ ("je" ?𞡏)
+ ("joo" ?𞡐)
+ ("jo" ?𞡑)
+ ("jjo" ?𞡒)
+
+ ("yi" ?𞡓)
+ ("ya" ?𞡔)
+ ("yu" ?𞡕)
+ ("yee" ?𞡖)
+ ("ye" ?𞡗)
+ ("yoo" ?𞡘)
+ ("yo" ?𞡙)
+
+ ("fi" ?𞡚)
+ ("fa" ?𞡛)
+ ("fu" ?𞡜)
+ ("fee" ?𞡝)
+ ("fe" ?𞡞)
+ ("foo" ?𞡟)
+ ("fo" ?𞡠)
+ ("fua" ?𞡡)
+ ("fan" ?𞡢)
+
+ ("nin" ?𞡣)
+ ("nan" ?𞡤)
+ ("nun" ?𞡥)
+ ("nen" ?𞡦)
+ ("non" ?𞡧)
+
+ ("hi" ?𞡨)
+ ("ha" ?𞡩)
+ ("hu" ?𞡪)
+ ("hee" ?𞡫)
+ ("he" ?𞡬)
+ ("hoo" ?𞡭)
+ ("ho" ?𞡮)
+ ("heei" ?𞡯)
+ ("hoou" ?𞡰)
+ ("hin" ?𞡱)
+ ("han" ?𞡲)
+ ("hun" ?𞡳)
+ ("hen" ?𞡴)
+ ("hon" ?𞡵)
+ ("huan" ?𞡶)
+
+ ("nggi" ?𞡷)
+ ("ngga" ?𞡸)
+ ("nggu" ?𞡹)
+ ("nggee" ?𞡺)
+ ("ngge" ?𞡻)
+ ("nggoo" ?𞡼)
+ ("nggo" ?𞡽)
+ ("nggaa" ?𞡾)
+ ("nggua" ?𞡿)
+ ("nngge" ?𞢀)
+ ("nnggoo" ?𞢁)
+ ("nnggo" ?𞢂)
+
+ ("gi" ?𞢃)
+ ("ga" ?𞢄)
+ ("gu" ?𞢅)
+ ("gee" ?𞢆)
+ ("guei" ?𞢇)
+ ("guan" ?𞢈)
+
+ ("ngen" ?𞢉)
+ ("ngon" ?𞢊)
+ ("nguan" ?𞢋)
+
+ ("pi" ?𞢌)
+ ("pa" ?𞢍)
+ ("pu" ?𞢎)
+ ("pee" ?𞢏)
+ ("pe" ?𞢐)
+ ("poo" ?𞢑)
+ ("po" ?𞢒)
+
+ ("mbi" ?𞢓)
+ ("mba" ?𞢔)
+ ("mbu" ?𞢕)
+ ("mbee" ?𞢖)
+ ("mmbee" ?𞢗)
+ ("mbe" ?𞢘)
+ ("mboo" ?𞢙)
+ ("mbo" ?𞢚)
+ ("mbuu" ?𞢛)
+ ("mmbe" ?𞢜)
+ ("mmboo" ?𞢝)
+ ("mmbo" ?𞢞)
+
+ ("kpi" ?𞢟)
+ ("kpa" ?𞢠)
+ ("kpu" ?𞢡)
+ ("kpee" ?𞢢)
+ ("kpe" ?𞢣)
+ ("kpoo" ?𞢤)
+ ("kpo" ?𞢥)
+
+ ("gbi" ?𞢦)
+ ("gba" ?𞢧)
+ ("gbu" ?𞢨)
+ ("gbee" ?𞢩)
+ ("gbe" ?𞢪)
+ ("gboo" ?𞢫)
+ ("gbo" ?𞢬)
+
+ ("ra" ?𞢭)
+
+ ("ndi" ?𞢮)
+ ("nda" ?𞢯)
+ ("ndu" ?𞢰)
+ ("ndee" ?𞢱)
+ ("nde" ?𞢲)
+ ("ndoo" ?𞢳)
+ ("ndo" ?𞢴)
+
+ ("nja" ?𞢵)
+ ("nju" ?𞢶)
+ ("njee" ?𞢷)
+ ("njoo" ?𞢸)
+
+ ("vi" ?𞢹)
+ ("va" ?𞢺)
+ ("vu" ?𞢻)
+ ("vee" ?𞢼)
+ ("ve" ?𞢽)
+ ("voo" ?𞢾)
+ ("vo" ?𞢿)
+
+ ("nyin" ?𞣀)
+ ("nyan" ?𞣁)
+ ("nyun" ?𞣂)
+ ("nyen" ?𞣃)
+ ("nyon" ?𞣄))
+
+(quail-define-package
+ "gothic" "Gothic" "𐌰" nil
+ "Input methid for the ancient Gothic script."
+ nil t t t t nil nil nil nil nil t)
+
+(quail-define-rules
+ ("q" ?𐌵)
+ ("w" ?𐍅)
+ ("e" ?𐌴)
+ ("r" ?𐍂)
+ ("t" ?𐍄)
+ ("y" ?𐌸)
+ ("u" ?𐌿)
+ ("i" ?𐌹)
+ ("o" ?𐍉)
+ ("p" ?𐍀)
+ ("a" ?𐌰)
+ ("s" ?𐍃)
+ ("d" ?𐌳)
+ ("f" ?𐍆)
+ ("g" ?𐌲)
+ ("h" ?𐌷)
+ ("j" ?𐌾)
+ ("k" ?𐌺)
+ ("l" ?𐌻)
+ ("z" ?𐌶)
+ ("x" ?𐍇)
+ ("c" ?𐍈)
+ ("v" ?𐍁)
+ ("V" ?𐍊)
+ ("b" ?𐌱)
+ ("n" ?𐌽)
+ ("m" ?𐌼))
+
+(quail-define-package
+ "coptic" "Coptic" "Ⲁ" nil "Coptic input method.
+
+ `\\=`' is used to switch levels instead of Alt-Gr."
+ nil t t t t nil nil nil nil nil t)
+
+(quail-define-rules
+ ("1" ?𐋡)
+ ("`1" ?1)
+ ("`!" ?𐋠)
+ ("2" ?𐋢)
+ ("`2" ?2)
+ ("3" ?𐋣)
+ ("`3" ?3)
+ ("4" ?𐋤)
+ ("`4" ?4)
+ ("5" ?𐋥)
+ ("`5" ?5)
+ ("6" ?𐋦)
+ ("`6" ?6)
+ ("7" ?𐋧)
+ ("`7" ?7)
+ ("8" ?𐋨)
+ ("`8" ?8)
+ ("9" ?𐋩)
+ ("`9" ?9)
+ ("10" ?𐋪)
+ ("20" ?𐋫)
+ ("30" ?𐋬)
+ ("40" ?𐋭)
+ ("50" ?𐋮)
+ ("60" ?𐋯)
+ ("70" ?𐋰)
+ ("80" ?𐋱)
+ ("90" ?𐋲)
+ ("100" ?𐋳)
+ ("200" ?𐋴)
+ ("300" ?𐋵)
+ ("400" ?𐋶)
+ ("500" ?𐋷)
+ ("600" ?𐋸)
+ ("700" ?𐋹)
+ ("800" ?𐋺)
+ ("900" ?𐋻)
+ ("1/2" ?⳽)
+
+ ("q" ?ⲑ)
+ ("Q" ?Ⲑ)
+ ("w" ?ⲱ)
+ ("W" ?Ⲱ)
+ ("e" ?ⲉ)
+ ("E" ?Ⲉ)
+ ("r" ?ⲣ)
+ ("R" ?Ⲣ)
+ ("t" ?ⲧ)
+ ("T" ?Ⲧ)
+ ("ti" ?ϯ)
+ ("Ti" ?Ϯ)
+ ("y" ?ⲏ)
+ ("Y" ?Ⲏ)
+ ("u" ?ⲩ)
+ ("U" ?Ⲩ)
+ ("i" ?ⲓ)
+ ("I" ?Ⲓ)
+ ("o" ?ⲟ)
+ ("O" ?Ⲟ)
+ ("p" ?ⲡ)
+ ("P" ?Ⲡ)
+ ("ps" ?ⲯ)
+ ("Ps" ?Ⲯ)
+ ("a" ?ⲁ)
+ ("A" ?Ⲁ)
+ ("s" ?ⲥ)
+ ("S" ?Ⲥ)
+ ("`s" ?ⲋ)
+ ("`S" ?Ⲋ)
+ ("sh" ?ϣ)
+ ("Sh" ?Ϣ)
+ ("d" ?ⲇ)
+ ("D" ?Ⲇ)
+ ("f" ?ⲫ)
+ ("F" ?Ⲫ)
+ ("g" ?ⲅ)
+ ("G" ?Ⲅ)
+ ("h" ?ϩ)
+ ("H" ?Ϩ)
+ ("j" ?ϫ)
+ ("J" ?Ϫ)
+ ("k" ?ⲕ)
+ ("K" ?Ⲕ)
+ ("kh" ?ⲭ)
+ ("Kh" ?Ⲭ)
+ ("l" ?ⲗ)
+ ("L" ?Ⲗ)
+ ("z" ?ⲍ)
+ ("Z" ?Ⲍ)
+ ("x" ?ⲝ)
+ ("X" ?Ⲝ)
+ ("`x" ?ϧ)
+ ("`X" ?Ϧ)
+ ("c" ?ϭ)
+ ("C" ?Ϭ)
+ ("v" ?ϥ)
+ ("V" ?Ϥ)
+ ("b" ?ⲃ)
+ ("B" ?Ⲃ)
+ ("n" ?ⲛ)
+ ("N" ?Ⲛ)
+ ("`n" ?⳯)
+ ("m" ?ⲙ)
+ ("M" ?Ⲙ)
+
+ ("`," ?⳰)
+ ("`<" ?⳱)
+ ("`." ?⳾)
+ ("`/" ?⳿))
+
(provide 'misc-lang)
;;; misc-lang.el ends here
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 634a3314361..c01c827a75e 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -244,9 +244,7 @@
(load "language/indonesian")
(load "indent")
-(let ((max-specpdl-size (max max-specpdl-size 1800)))
- ;; A particularly demanding file to load; 1600 does not seem to be enough.
- (load "emacs-lisp/cl-generic"))
+(load "emacs-lisp/cl-generic")
(load "simple")
(load "emacs-lisp/seq")
(load "emacs-lisp/nadvice")
diff --git a/lisp/mail/emacsbug.el b/lisp/mail/emacsbug.el
index a85ceaf1a5a..60f733435a6 100644
--- a/lisp/mail/emacsbug.el
+++ b/lisp/mail/emacsbug.el
@@ -300,7 +300,7 @@ usually do not have translators for other languages.\n\n")))
(let ((txt (delete-and-extract-region (1+ user-point) (point))))
(insert (propertize "\n" 'display txt)))
- (emacs-bug--system-description)
+ (emacs-build-description)
(insert "Configured features:\n" system-configuration-features "\n\n")
(fill-region (line-beginning-position -1) (point))
(when (and (featurep 'native-compile)
@@ -386,7 +386,10 @@ copy text to your preferred mail program.\n"
(buffer-substring-no-properties (point-min) (point)))
(goto-char user-point)))
-(defun emacs-bug--system-description ()
+;;;###autoload
+(defun emacs-build-description ()
+ "Insert a description of the current Emacs build in the current buffer."
+ (interactive)
(let ((start (point)))
(insert "\nIn " (emacs-version))
(if emacs-build-system
@@ -521,7 +524,7 @@ Message buffer where you can explain more about the patch."
(compose-mail-other-window report-emacs-bug-address subject)
(message-goto-body)
(insert "\n\n\n")
- (emacs-bug--system-description)
+ (emacs-build-description)
(mml-attach-file file "text/patch" nil "attachment")
(message-goto-body)
(message "Write a description of the patch and use %s to send it"
diff --git a/lisp/mail/feedmail.el b/lisp/mail/feedmail.el
index 989a8b3cd67..2ae916e3ac1 100644
--- a/lisp/mail/feedmail.el
+++ b/lisp/mail/feedmail.el
@@ -614,29 +614,12 @@ to arrange for the message to get a From: line."
(defcustom feedmail-sendmail-f-doesnt-sell-me-out nil
- "Whether sendmail should issue a warning header if called with \"-f\".
-The sendmail program has a useful feature to let you set the envelope FROM
-address via a command line option, \"-f\". Unfortunately, it also has a widely
-disliked default behavior of selling you out if you do that by inserting
-an unattractive warning in the headers. It looks something like this:
-
- X-Authentication-Warning: u1.example.com: niceguy set
- sender to niceguy@example.com using -f
-
-It is possible to configure sendmail to not do this, but such a
-reconfiguration is not an option for many users. As this is the
-default behavior of most sendmail installations, one can mostly
-only wish it were otherwise. If feedmail believes the sendmail
-program will sell you out this way, it won't use the \"-f\"
-option when calling sendmail. If it doesn't think sendmail will
-sell you out, it will use the \"-f\" \(since it is a handy
-feature). You control what feedmail thinks with this variable.
-The default is nil, meaning that feedmail will believe that
-sendmail will sell you out."
+ "If non-nil, call \"sendmail\" with \"-f\".
+See `message-sendmail-f-is-evil' for an explanation of what the
+\"-f\" parameter does."
:version "24.1"
:group 'feedmail-headers
- :type 'boolean
-)
+ :type 'boolean)
(defcustom feedmail-deduce-envelope-from t
diff --git a/lisp/mail/hashcash.el b/lisp/mail/hashcash.el
index eebb140088e..5136e11c899 100644
--- a/lisp/mail/hashcash.el
+++ b/lisp/mail/hashcash.el
@@ -57,8 +57,7 @@
"The default number of bits to pay to unknown users.
If this is zero, no payment header will be generated.
See `hashcash-payment-alist'."
- :type 'natnum
- :group 'hashcash)
+ :type 'natnum)
(defcustom hashcash-payment-alist '()
"An association list mapping email addresses to payment amounts.
@@ -72,46 +71,39 @@ present, is the string to be hashed; if not present ADDR will be used."
(list :tag "Replace hash input"
(string :name "Address")
(string :name "Hash input")
- (integer :name "Amount"))))
- :group 'hashcash)
+ (integer :name "Amount")))))
(defcustom hashcash-default-accept-payment 20
"The default minimum number of bits to accept on incoming payments."
- :type 'natnum
- :group 'hashcash)
+ :type 'natnum)
(defcustom hashcash-accept-resources `((,user-mail-address nil))
"An association list mapping hashcash resources to payment amounts.
Resources named here are to be accepted in incoming payments. If the
corresponding AMOUNT is NIL, the value of `hashcash-default-accept-payment'
is used instead."
- :type 'alist
- :group 'hashcash)
+ :type 'alist)
(define-obsolete-variable-alias 'hashcash-path 'hashcash-program "24.4")
(defcustom hashcash-program "hashcash"
"The name of the hashcash executable.
If this is not in your PATH, specify an absolute file name."
- :type '(choice (const nil) file)
- :group 'hashcash)
+ :type '(choice (const nil) file))
(defcustom hashcash-extra-generate-parameters '("-Z2")
"A list of parameter strings passed to `hashcash-program' when minting.
For example, on very old hardware, you may want to set this
to (\"-Z0\") to disable compression."
:type '(repeat string)
- :version "29.1"
- :group 'hashcash)
+ :version "29.1")
(defcustom hashcash-double-spend-database "hashcash.db"
"The name of the double-spending database file."
- :type 'file
- :group 'hashcash)
+ :type 'file)
(defcustom hashcash-in-news nil
"Specifies whether or not hashcash payments should be made to newsgroups."
- :type 'boolean
- :group 'hashcash)
+ :type 'boolean)
(defvar hashcash-process-alist nil
"Alist of asynchronous hashcash processes and buffers.")
@@ -316,6 +308,7 @@ Set ASYNC to t to start asynchronous calculation. (See
(save-excursion
(save-restriction
(message-narrow-to-headers)
+ (goto-char (point-max))
(let ((to (hashcash-strip-quoted-names (mail-fetch-field "To" nil t)))
(cc (hashcash-strip-quoted-names (mail-fetch-field "Cc" nil t)))
(ng (hashcash-strip-quoted-names (mail-fetch-field "Newsgroups"
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index fed0a2057bc..f095d5e9c08 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -372,11 +372,17 @@ If nil, display all header fields except those matched by
:group 'rmail-headers)
;;;###autoload
-(defcustom rmail-retry-ignored-headers (purecopy "^x-authentication-warning:\\|^x-detected-operating-system:\\|^x-spam[-a-z]*:\\|content-type:\\|content-transfer-encoding:\\|mime-version:\\|message-id:")
+(defcustom rmail-retry-ignored-headers
+ (concat "^x-authentication-warning:\\|^x-detected-operating-system:\\|"
+ "^x-spam[-a-z]*:\\|^arc-.*:\\|"
+ "^content-type:\\|^content-transfer-encoding:\\|"
+ "^mime-version:\\|^message-id:\\|^x-google-smtp-source:\\|"
+ "^x-received:\\|^received-spf:\\|"
+ "^authentication-results:\\|^dkim-signature:")
"Headers that should be stripped when retrying a failed message."
:type '(choice regexp (const :value nil :tag "None"))
:group 'rmail-headers
- :version "23.2") ; added x-detected-operating-system, x-spam
+ :version "29.1")
;;;###autoload
(defcustom rmail-highlighted-headers (purecopy "^From:\\|^Subject:")
@@ -4687,15 +4693,23 @@ Argument MIME is non-nil if this is a mime message."
(save-excursion
(goto-char (point-min))
(while (re-search-forward "--------------[0-9a-zA-Z]+\n" nil t)
- (let ((delim (concat (substring (match-string 0) 0 -1) "--\n")))
+ ;; The ending delimiter is a start delimiter if another section follows.
+ ;; Otherwise it is an end delimiter, with -- affixed.
+ (let ((delim (concat (substring (match-string 0) 0 -1) "\\(\\|--\\)\n")))
(when (looking-at "\
Content-Type: text/[a-z]+; charset=UTF-8; format=flowed
Content-Transfer-Encoding: base64\n")
(goto-char (match-end 0))
+ ;; Sometimes the attachment's headers are followed by blank lines
+ (while (eolp)
+ (forward-line 1))
(let ((start (point))
(inhibit-read-only t))
- (search-forward delim)
+ (re-search-forward delim)
(forward-line -1)
+ ;; Sometimes the attachment's contents are followed by blank lines
+ (while (save-excursion (forward-line -1) (eolp))
+ (forward-line -1))
(base64-decode-region start (point))
(forward-line 1)))))))
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index 0ad934107d3..9a04d890973 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -2831,9 +2831,7 @@ removed and entries from `mh-invisible-header-fields' are added."
(setq mh-invisible-header-fields-compiled
(concat
"^"
- ;; workaround for insufficient default
- (let ((max-specpdl-size 1000))
- (regexp-opt fields t))))
+ (regexp-opt fields t)))
(setq mh-invisible-header-fields-compiled nil))))
;; Compile invisible header fields.
diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el
index be1b7642eb3..38a8216dc0c 100644
--- a/lisp/mh-e/mh-junk.el
+++ b/lisp/mh-e/mh-junk.el
@@ -402,7 +402,7 @@ information can be used so that you can replace multiple
Bogofilter is a Bayesian spam filtering program. Get it from your
local distribution or from the bogofilter web site at URL
-`http://bogofilter.sourceforge.net/'.
+`https://bogofilter.sourceforge.io/'.
Bogofilter is taught by running:
@@ -487,7 +487,7 @@ See `mh-bogofilter-blocklist' for more information."
SpamProbe is a Bayesian spam filtering program. Get it from your
local distribution or from the SpamProbe web site at URL
-`http://spamprobe.sourceforge.net'.
+`https://spamprobe.sourceforge.net'.
To use SpamProbe, add the following recipes to \".procmailrc\":
diff --git a/lisp/minibuf-eldef.el b/lisp/minibuf-eldef.el
index ba7e68eb81d..935c9111ee6 100644
--- a/lisp/minibuf-eldef.el
+++ b/lisp/minibuf-eldef.el
@@ -110,8 +110,7 @@ should be displayed in its place.")
"Set up a minibuffer for `minibuffer-electric-default-mode'.
The prompt and initial input should already have been inserted."
(let ((regexps minibuffer-default-in-prompt-regexps)
- (match nil)
- (inhibit-point-motion-hooks t))
+ (match nil))
(save-excursion
(save-restriction
;; Narrow to only the prompt.
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index 2d528c4862c..1597f3651a5 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -1294,6 +1294,11 @@ currently selected window instead."
(let ((file (url-unhex-string (url-filename parsed))))
(when-let ((coding (browse-url--file-name-coding-system)))
(setq file (decode-coding-string file 'utf-8)))
+ ;; The local-part of file: URLs on Windows is supposed to
+ ;; start with an extra slash.
+ (when (eq system-type 'windows-nt)
+ (setq file (replace-regexp-in-string
+ "\\`/\\([a-z]:\\)" "\\1" file)))
(funcall func file))
(let ((file-name-handler-alist
(cons (cons url-handler-regexp 'url-file-handler)
diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el
index 43dd28ff6dc..4c52382c672 100644
--- a/lisp/net/dictionary.el
+++ b/lisp/net/dictionary.el
@@ -59,7 +59,7 @@ the existing connection."
(defgroup dictionary nil
"Client for accessing the dictd server based dictionaries."
- :group 'hypermedia)
+ :group 'applications)
(defgroup dictionary-proxy nil
"Proxy configuration options for the dictionary client."
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 6ed0719eca6..414de931c4a 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -315,7 +315,8 @@ parameter, and should return the (possibly) transformed URL."
(defvar-keymap eww-link-keymap
:parent shr-map
- "RET" #'eww-follow-link)
+ "RET" #'eww-follow-link
+ "<mouse-2>" #'eww-follow-link)
(defvar-keymap eww-image-link-keymap
:parent shr-map
@@ -415,13 +416,11 @@ For more information, see Info node `(eww) Top'."
(defun eww-retrieve (url callback cbargs)
(cond
((null eww-retrieve-command)
- (url-retrieve url #'eww-render
- (list url nil (current-buffer))))
+ (url-retrieve url #'eww-render cbargs))
((eq eww-retrieve-command 'sync)
- (let ((orig-buffer (current-buffer))
- (data-buffer (url-retrieve-synchronously url)))
+ (let ((data-buffer (url-retrieve-synchronously url)))
(with-current-buffer data-buffer
- (eww-render nil url nil orig-buffer))))
+ (apply #'eww-render nil url cbargs))))
(t
(let ((buffer (generate-new-buffer " *eww retrieve*"))
(error-buffer (generate-new-buffer " *eww error*")))
@@ -626,7 +625,10 @@ The renaming scheme is performed in accordance with
(setq eww-history-position 0)
(and last-coding-system-used
(set-buffer-file-coding-system last-coding-system-used))
- (run-hooks 'eww-after-render-hook)))
+ (run-hooks 'eww-after-render-hook)
+ ;; Enable undo again so that undo works in text input
+ ;; boxes.
+ (setq buffer-undo-list nil)))
(kill-buffer data-buffer))))
(defun eww-parse-headers ()
@@ -928,7 +930,8 @@ The renaming scheme is performed in accordance with
;; May be set later if there's a next/prev link.
(setq-local multi-isearch-next-buffer-function nil)
(unless (eq major-mode 'eww-mode)
- (eww-mode)))
+ (eww-mode))
+ (buffer-disable-undo))
(defun eww-current-url nil
"Return URI of the Web page the current EWW buffer is visiting."
@@ -1176,8 +1179,28 @@ the like."
'((url . eww--url-at-point))))
(setq-local bookmark-make-record-function #'eww-bookmark-make-record)
(buffer-disable-undo)
+ (setq-local shr-url-transformer #'eww--transform-url)
+ ;; Also rescale images when rescaling the text.
+ (add-hook 'text-scale-mode-hook #'eww--rescale-images nil t)
(setq buffer-read-only t))
+(defvar text-scale-mode)
+(defvar text-scale-mode-amount)
+(defun eww--rescale-images ()
+ (let ((scaling (if text-scale-mode
+ (+ 1 (* text-scale-mode-amount 0.1))
+ 1)))
+ (save-excursion
+ (goto-char (point-min))
+ (while-let ((match (text-property-search-forward
+ 'display nil (lambda (_ value) (imagep value)))))
+ (let ((image (prop-match-value match)))
+ (unless (image-property image :original-scale)
+ (setf (image-property image :original-scale)
+ (or (image-property image :scale) 1)))
+ (setf (image-property image :scale)
+ (* (image-property image :original-scale) scaling)))))))
+
(defun eww--url-at-point ()
"`thing-at-point' provider function."
(get-text-property (point) 'shr-url))
@@ -1606,7 +1629,7 @@ See URL `https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input'.")
(unless (= start (point))
(put-text-property start (1+ start) 'help-echo "Input field")
;; Mark this as an element we can TAB to.
- (put-text-property start (1+ start) 'shr-url dom))))
+ (put-text-property start (1+ start) 'shr-tab-stop t))))
(defun eww-tag-select (dom)
(shr-ensure-paragraph)
@@ -1878,7 +1901,8 @@ If EXTERNAL is double prefix, browse in new buffer."
eww-mode)
(mouse-set-point mouse-event)
(let* ((orig-url (get-text-property (point) 'shr-url))
- (url (eww--transform-url orig-url)))
+ (url (eww--transform-url orig-url))
+ target)
(cond
((not url)
(message "No link under point"))
@@ -1890,12 +1914,17 @@ If EXTERNAL is double prefix, browse in new buffer."
(funcall browse-url-secondary-browser-function url)
(shr--blink-link))
;; This is a #target url in the same page as the current one.
- ((and (url-target (url-generic-parse-url url))
+ ((and (setq target (url-target (url-generic-parse-url url)))
(eww-same-page-p url (plist-get eww-data :url)))
- (let ((dom (plist-get eww-data :dom)))
+ (let ((point (point)))
(eww-save-history)
(plist-put eww-data :url url)
- (eww-display-html 'utf-8 url dom nil (current-buffer))))
+ (goto-char (point-min))
+ (if-let ((match (text-property-search-forward 'shr-target-id target #'member)))
+ (goto-char (prop-match-beginning match))
+ (goto-char (if (equal target "top")
+ (point-min)
+ point)))))
(t
(eww-browse-url orig-url external)))))
diff --git a/lisp/net/goto-addr.el b/lisp/net/goto-addr.el
index 99ed14ca8b4..86cf98004ba 100644
--- a/lisp/net/goto-addr.el
+++ b/lisp/net/goto-addr.el
@@ -164,52 +164,51 @@ and `goto-address-fontify-p'."
;; Clean up from any previous go.
(goto-address-unfontify (or start (point-min)) (or end (point-max)))
(save-excursion
- (let ((inhibit-point-motion-hooks t))
+ (goto-char (or start (point-min)))
+ (when (or (eq t goto-address-fontify-maximum-size)
+ (< (- (or end (point-max)) (point))
+ goto-address-fontify-maximum-size))
+ (while (re-search-forward goto-address-url-regexp end t)
+ (let* ((s (match-beginning 0))
+ (e (match-end 0))
+ this-overlay)
+ (when (or (not goto-address-prog-mode)
+ ;; This tests for both comment and string
+ ;; syntax.
+ (nth 8 (syntax-ppss)))
+ (setq this-overlay (make-overlay s e))
+ (and goto-address-fontify-p
+ (overlay-put this-overlay 'face goto-address-url-face))
+ (overlay-put this-overlay 'evaporate t)
+ (overlay-put this-overlay
+ 'mouse-face goto-address-url-mouse-face)
+ (overlay-put this-overlay 'follow-link t)
+ (overlay-put this-overlay
+ 'help-echo "mouse-2, C-c RET: follow URL")
+ (overlay-put this-overlay
+ 'keymap goto-address-highlight-keymap)
+ (overlay-put this-overlay 'goto-address t))))
(goto-char (or start (point-min)))
- (when (or (eq t goto-address-fontify-maximum-size)
- (< (- (or end (point-max)) (point))
- goto-address-fontify-maximum-size))
- (while (re-search-forward goto-address-url-regexp end t)
- (let* ((s (match-beginning 0))
- (e (match-end 0))
- this-overlay)
- (when (or (not goto-address-prog-mode)
- ;; This tests for both comment and string
- ;; syntax.
- (nth 8 (syntax-ppss)))
- (setq this-overlay (make-overlay s e))
- (and goto-address-fontify-p
- (overlay-put this-overlay 'face goto-address-url-face))
- (overlay-put this-overlay 'evaporate t)
- (overlay-put this-overlay
- 'mouse-face goto-address-url-mouse-face)
- (overlay-put this-overlay 'follow-link t)
- (overlay-put this-overlay
- 'help-echo "mouse-2, C-c RET: follow URL")
- (overlay-put this-overlay
- 'keymap goto-address-highlight-keymap)
- (overlay-put this-overlay 'goto-address t))))
- (goto-char (or start (point-min)))
- (while (re-search-forward goto-address-mail-regexp end t)
- (let* ((s (match-beginning 0))
- (e (match-end 0))
- this-overlay)
- (when (or (not goto-address-prog-mode)
- ;; This tests for both comment and string
- ;; syntax.
- (nth 8 (syntax-ppss)))
- (setq this-overlay (make-overlay s e))
- (and goto-address-fontify-p
- (overlay-put this-overlay 'face goto-address-mail-face))
- (overlay-put this-overlay 'evaporate t)
- (overlay-put this-overlay 'mouse-face
- goto-address-mail-mouse-face)
- (overlay-put this-overlay 'follow-link t)
- (overlay-put this-overlay
- 'help-echo "mouse-2, C-c RET: mail this address")
- (overlay-put this-overlay
- 'keymap goto-address-highlight-keymap)
- (overlay-put this-overlay 'goto-address t))))))))
+ (while (re-search-forward goto-address-mail-regexp end t)
+ (let* ((s (match-beginning 0))
+ (e (match-end 0))
+ this-overlay)
+ (when (or (not goto-address-prog-mode)
+ ;; This tests for both comment and string
+ ;; syntax.
+ (nth 8 (syntax-ppss)))
+ (setq this-overlay (make-overlay s e))
+ (and goto-address-fontify-p
+ (overlay-put this-overlay 'face goto-address-mail-face))
+ (overlay-put this-overlay 'evaporate t)
+ (overlay-put this-overlay 'mouse-face
+ goto-address-mail-mouse-face)
+ (overlay-put this-overlay 'follow-link t)
+ (overlay-put this-overlay
+ 'help-echo "mouse-2, C-c RET: mail this address")
+ (overlay-put this-overlay
+ 'keymap goto-address-highlight-keymap)
+ (overlay-put this-overlay 'goto-address t)))))))
(defun goto-address-fontify-region (start end)
"Fontify URLs and e-mail addresses in the given region."
diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el
index fd244a97b1a..aa0c1726553 100644
--- a/lisp/net/mailcap.el
+++ b/lisp/net/mailcap.el
@@ -125,7 +125,7 @@ is consulted."
("vnd\\.ms-excel"
(viewer . "gnumeric %s")
(test . (getenv "DISPLAY"))
- (type . "application/vnd.ms-excel"))
+ (type . "application/vnd\\.ms-excel"))
("octet-stream"
(viewer . mailcap-save-binary-file)
(non-viewer . t)
@@ -724,7 +724,7 @@ appropriately.
The format of INFO is described in `mailcap-mime-data'.
-STORAGE should be a symbol refering to a variable. The value of
+STORAGE should be a symbol referring to a variable. The value of
this variable should have the same format as `mailcap-mime-data'.
STORAGE defaults to `mailcap--computed-mime-data'.
@@ -979,7 +979,7 @@ If NO-DECODE is non-nil, don't decode STRING."
(".vox" . "audio/basic")
(".vrml" . "x-world/x-vrml")
(".wav" . "audio/x-wav")
- (".xls" . "application/vnd.ms-excel")
+ (".xls" . "application/vnd\\.ms-excel")
(".wrl" . "x-world/x-vrml")
(".xbm" . "image/xbm")
(".xpm" . "image/xpm")
@@ -1051,7 +1051,8 @@ If FORCE, re-parse even if already parsed."
(setq save-pos (point))
(skip-chars-forward "^ \t\n")
(downcase-region save-pos (point))
- (setq type (buffer-substring save-pos (point)))
+ (setq type (mailcap--regexp-quote-type
+ (buffer-substring save-pos (point))))
(while (not (eolp))
(skip-chars-forward " \t")
(setq save-pos (point))
@@ -1064,6 +1065,12 @@ If FORCE, re-parse even if already parsed."
(setq mailcap-mime-extensions (append extns mailcap-mime-extensions)
extns nil)))))
+(defun mailcap--regexp-quote-type (type)
+ (if (not (string-search "/" type))
+ type
+ (pcase-let ((`(,major ,minor) (split-string type "/")))
+ (concat major "/" (regexp-quote minor)))))
+
(defun mailcap-extension-to-mime (extn)
"Return the MIME content type of the file extensions EXTN."
(mailcap-parse-mimetypes)
diff --git a/lisp/net/pop3.el b/lisp/net/pop3.el
index 9d59ddf978d..1bd52c7a56c 100644
--- a/lisp/net/pop3.el
+++ b/lisp/net/pop3.el
@@ -23,6 +23,8 @@
;;; Commentary:
+;; Post Office Protocol version 3 (RFC 1460) interface.
+;;
;; Most of the standard Post Office Protocol version 3 (RFC 1460) commands
;; are implemented. The LIST command has not been implemented due to lack
;; of actual usefulness.
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index abb67da95f0..eadaf00c4b8 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -1340,12 +1340,91 @@ The list is updated automatically by `defun-rcirc-command'.")
'set-rcirc-encode-coding-system
"28.1")
+(defun rcirc-format (pre &optional replace)
+ "Insert markup formatting PRE.
+PRE and \"^O\" (ASCII #x0f) will either be inserted around the
+current point respectively or the active region, if present.
+This function an auxiliary function is not meant to be used
+directly, but is invoked by other commands. If the optional
+argument REPLACE is non-nil, first remove any formatting before
+inserting the new one."
+ (when replace (rcirc-unformat))
+ (save-excursion
+ (if (use-region-p)
+ (let ((beg (region-beginning)))
+ (goto-char (region-end))
+ (insert "")
+ (goto-char beg)
+ (insert pre))
+ (insert pre "")))
+ (when (or (not (region-active-p)) (< (point) (mark)))
+ (forward-char (length pre))))
+
+(defun rcirc-unformat ()
+ "Remove the closes formatting found closes to the current point."
+ (interactive)
+ (save-excursion
+ (when (and (search-backward-regexp (rx (or "" "" "" "" ""))
+ rcirc-prompt-end-marker t)
+ (looking-at (rx (group (or "" "" "" "" ""))
+ (*? nonl)
+ (group ""))))
+ (replace-match "" nil nil nil 2)
+ (replace-match "" nil nil nil 1))))
+
+(defun rcirc-format-bold (replace)
+ "Insert bold formatting.
+If REPLACE is non-nil or a prefix argument is given, any prior
+formatting will be replaced before the bold formatting is
+inserted."
+ (interactive "P")
+ (rcirc-format "" replace))
+
+(defun rcirc-format-italic (replace)
+ "Insert italic formatting.
+If REPLACE is non-nil or a prefix argument is given, any prior
+formatting will be replaced before the italic formatting is
+inserted."
+ (interactive "P")
+ (rcirc-format "" replace))
+
+(defun rcirc-format-underline (replace)
+ "Insert underlining formatting.
+If REPLACE is non-nil or a prefix argument is given, any prior
+formatting will be replaced before the underline formatting is
+inserted."
+ (interactive "P")
+ (rcirc-format "" replace))
+
+(defun rcirc-format-strike-trough (replace)
+ "Insert strike-trough formatting.
+If REPLACE is non-nil or a prefix argument is given, any prior
+formatting will be replaced before the strike-trough formatting
+is inserted."
+ (interactive "P")
+ (rcirc-format "" replace))
+
+(defun rcirc-format-fixed-width (replace)
+ "Insert fixed-width formatting.
+If REPLACE is non-nil or a prefix argument is given, any prior
+formatting will be replaced before the fixed width formatting is
+inserted."
+ (interactive "P")
+ (rcirc-format "" replace))
+
(defvar-keymap rcirc-mode-map
:doc "Keymap for rcirc mode."
"RET" #'rcirc-send-input
"M-p" #'rcirc-insert-prev-input
"M-n" #'rcirc-insert-next-input
"TAB" #'completion-at-point
+ "C-c C-f C-b" #'rcirc-format-bold
+ "C-c C-f C-i" #'rcirc-format-italic
+ "C-c C-f C-u" #'rcirc-format-underline
+ "C-c C-f C-s" #'rcirc-format-strike-trough
+ "C-c C-f C-f" #'rcirc-format-fixed-width
+ "C-c C-f C-t" #'rcirc-format-fixed-width ;as in AucTeX
+ "C-c C-f C-d" #'rcirc-unformat
"C-c C-b" #'rcirc-browse-url
"C-c C-c" #'rcirc-edit-multiline
"C-c C-j" #'rcirc-cmd-join
@@ -1725,6 +1804,13 @@ extracted."
(defvar-keymap rcirc-multiline-minor-mode-map
:doc "Keymap for multiline mode in rcirc."
+ "C-c C-f C-b" #'rcirc-format-bold
+ "C-c C-f C-i" #'rcirc-format-italic
+ "C-c C-f C-u" #'rcirc-format-underline
+ "C-c C-f C-s" #'rcirc-format-strike-trough
+ "C-c C-f C-f" #'rcirc-format-fixed-width
+ "C-c C-f C-t" #'rcirc-format-fixed-width ;as in AucTeX
+ "C-c C-f C-d" #'rcirc-unformat
"C-c C-c" #'rcirc-multiline-minor-submit
"C-x C-s" #'rcirc-multiline-minor-submit
"C-c C-k" #'rcirc-multiline-minor-cancel
@@ -1925,7 +2011,8 @@ PROCESS is the process object for the current connection."
rcirc-markup-my-nick
rcirc-markup-urls
rcirc-markup-keywords
- rcirc-markup-bright-nicks)
+ rcirc-markup-bright-nicks
+ rcirc-markup-bridge-bots)
"List of functions used to manipulate text before it is printed.
Each function takes two arguments, SENDER, and RESPONSE. The
@@ -1988,9 +2075,6 @@ connection."
'rcirc-msgid (rcirc-get-tag "msgid"))
(propertize "\n" 'hard t))
- ;; squeeze spaces out of text before rcirc-text
- (fill-region (point-min) (point-max))
-
(goto-char (or (next-single-property-change (point-min) 'rcirc-text)
(point)))
(when (rcirc-buffer-process)
@@ -2092,9 +2176,11 @@ connection."
(defun rcirc-generate-log-filename (process target)
"Return filename for log file based on PROCESS and TARGET."
- (if target
- (rcirc-generate-new-buffer-name process target)
- (process-name process)))
+ (concat
+ (if target
+ (rcirc-generate-new-buffer-name process target)
+ (process-name process))
+ ".log"))
(defcustom rcirc-log-filename-function 'rcirc-generate-log-filename
"A function to generate the filename used by rcirc's logging facility.
@@ -2220,24 +2306,27 @@ PROCESS is the process object for the current connection."
(puthash nick newchans rcirc-nick-table)
(remhash nick rcirc-nick-table)))))
+(defvar rcirc-pseudo-nicks)
(defun rcirc-channel-nicks (process target)
"Return the list of nicks associated with TARGET sorted by last activity.
PROCESS is the process object for the current connection."
(when target
(if (rcirc-channel-p target)
- (with-rcirc-process-buffer process
- (let (nicks)
- (maphash
- (lambda (k v)
- (let ((record (assoc-string target v t)))
- (if record
- (setq nicks (cons (cons k (cdr record)) nicks)))))
- rcirc-nick-table)
- (mapcar (lambda (x) (car x))
- (sort nicks (lambda (x y)
- (let ((lx (or (cdr x) 0))
- (ly (or (cdr y) 0)))
- (< ly lx)))))))
+ (let ((pseudo-nicks (mapcar #'list rcirc-pseudo-nicks)))
+ (with-rcirc-process-buffer process
+ (let (nicks)
+ (maphash
+ (lambda (k v)
+ (let ((record (assoc-string target v t)))
+ (if record
+ (setq nicks (cons (cons k (cdr record)) nicks)))))
+ rcirc-nick-table)
+ (mapcar (lambda (x) (car x))
+ (sort (nconc pseudo-nicks nicks)
+ (lambda (x y)
+ (let ((lx (or (cdr x) 0))
+ (ly (or (cdr y) 0)))
+ (< ly lx))))))))
(list target))))
(defun rcirc-ignore-update-automatic (nick)
@@ -2911,6 +3000,74 @@ If ARG is given, opens the URL in a new browser window."
(insert (rcirc-facify (format-time-string rcirc-time-format time)
'rcirc-timestamp))))
+(defvar-local rcirc-pseudo-nicks '()
+ "List of virtual nicks detected in a channel.
+These are collected by `rcirc-markup-bridge-bots' and don't
+constitute actual users in the current channel. Usually these
+are bridged via a some bot as described in
+`rcirc-bridge-bot-alist'.")
+
+(defcustom rcirc-bridge-bot-alist '()
+ "Alist for handling bouncers by `rcirc-markup-bridge-bots'.
+Each entry has the form (NAME . REGEXP), where NAME is the user
+name of a bouncer and REGEXP is a pattern used to match the
+message. The matching part of the message will be stripped from
+the message, and the first match group will replace the user name
+of the bot. Any matched name will noted and used in some cases
+for nick completion."
+ :type '(alist :key-type (string :tag "Bot name")
+ :value-type regexp)
+ :version "29.1")
+
+(defface rcirc-bridged-nick
+ '((t :inherit highlight))
+ "Face used for pseudo-nick ."
+ :version "29.1")
+
+(defun rcirc-markup-bridge-bots (sender response)
+ "Detect and reformat bridged messages to appear more natural.
+The user option `rcirc-bridge-bot-alist' specified what SENDER to
+handle. This function only operates on direct messages (as
+indicated by RESPONSE)."
+ (catch 'quit
+ (atomic-change-group
+ (save-match-data
+ (when-let* (((string= response "PRIVMSG"))
+ (regexp (alist-get sender rcirc-bridge-bot-alist
+ nil nil #'string=))
+ ((search-forward-regexp regexp nil t))
+ (nick (match-string-no-properties 1)))
+ (replace-match "") ;delete the bot string
+ (unless (member nick rcirc-pseudo-nicks)
+ (push nick rcirc-pseudo-nicks))
+ (goto-char (point-min))
+ (let ((fmt (alist-get "PRIVMSG" rcirc-response-formats
+ nil nil #'string=))
+ (hl-face (cond ((member sender rcirc-bright-nicks)
+ 'rcirc-bright-nick)
+ ((member sender rcirc-dim-nicks)
+ 'rcirc-dim-nick)
+ (t 'rcirc-other-nick)))
+ hl-username-p)
+ (when (string-match (rx (* "%%") "%" (group (or ?N ?n))) fmt)
+ (when (string= (match-string 1 fmt) "N")
+ (setq hl-username-p t))
+ (search-forward-regexp
+ (format-spec
+ (alist-get "PRIVMSG" rcirc-response-formats
+ nil nil #'string=)
+ `((?m . "") (?r . "") (?t . "") (?f . "")
+ (?N . ,(rx (group (+? nonl))))
+ (?n . ,(rx (group (+? nonl))))))
+ nil t)
+ (replace-match
+ (propertize
+ nick
+ 'help-echo (format "Message bridged via %s" sender)
+ 'face `(,@(and hl-username-p (list hl-face))
+ rcirc-bridged-nick))
+ nil t nil 1))))))))
+
(defun rcirc-markup-attributes (_sender _response)
"Highlight IRC markup, indicated by ASCII control codes."
(while (re-search-forward
@@ -2966,10 +3123,8 @@ If ARG is given, opens the URL in a new browser window."
((<= 0 bg (1- (length rcirc-color-codes)))))
(setq background (aref rcirc-color-codes bg)))
(rcirc-add-face (match-beginning 0) (match-end 0)
- `(face (:foreground
- ,foreground
- :background
- ,background))))))
+ `(face (,@(and foreground (list :foreground foreground))
+ ,@(and background (list :background background))))))))
(defun rcirc-remove-markup-codes (_sender _response)
"Remove ASCII control codes used to designate markup."
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 248faeb223c..75992bc62a4 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -295,6 +295,11 @@ and other things:
(make-composed-keymap shr-map image-map)
shr-map))
+(defvar shr-url-transformer #'identity
+ "Function to transform URLs.
+It's called with the URL as the parameter, and should return the
+ URL to use.")
+
;; Public functions and commands.
(declare-function libxml-parse-html-region "xml.c"
(start end &optional base-url discard-comments))
@@ -368,7 +373,6 @@ DOM should be a parse tree as generated by
shr-width
(* shr-width (frame-char-width)))
(shr--window-width)))
- (max-specpdl-size max-specpdl-size)
(shr--link-targets nil)
(hscroll (window-hscroll))
;; `bidi-display-reordering' is supposed to be only used for
@@ -499,7 +503,7 @@ Value is a pair of positions (START . END) if there is a non-nil
(defun shr-next-link ()
"Skip to the next link."
(interactive)
- (let ((match (text-property-search-forward 'shr-url nil nil t)))
+ (let ((match (text-property-search-forward 'shr-tab-stop nil nil t)))
(if (not match)
(message "No next link")
(goto-char (prop-match-beginning match))
@@ -508,7 +512,7 @@ Value is a pair of positions (START . END) if there is a non-nil
(defun shr-previous-link ()
"Skip to the previous link."
(interactive)
- (if (not (text-property-search-backward 'shr-url nil nil t))
+ (if (not (text-property-search-backward 'shr-tab-stop nil nil t))
(message "No previous link")
(message "%s" (get-text-property (point) 'help-echo))))
@@ -620,41 +624,34 @@ size, and full-buffer size."
(shr-stylesheet shr-stylesheet)
(shr-depth (1+ shr-depth))
(start (point)))
- ;; shr uses many frames per nested node.
- (if (and (> shr-depth (/ max-specpdl-size 15))
- (not (and shr-offer-extend-specpdl
- (y-or-n-p "Too deeply nested to render properly; increase `max-specpdl-size'?")
- (setq max-specpdl-size (* max-specpdl-size 2)))))
- (setq shr-warning
- "Not rendering the complete page because of too-deep nesting")
+ (when style
+ (if (string-match-p "color\\|display\\|border-collapse" style)
+ (setq shr-stylesheet (nconc (shr-parse-style style)
+ shr-stylesheet))
+ (setq style nil)))
+ ;; If we have a display:none, then just ignore this part of the DOM.
+ (unless (or (equal (cdr (assq 'display shr-stylesheet)) "none")
+ (and shr-discard-aria-hidden
+ (equal (dom-attr dom 'aria-hidden) "true")))
+ ;; We don't use shr-indirect-call here, since shr-descend is
+ ;; the central bit of shr.el, and should be as fast as
+ ;; possible. Having one more level of indirection with its
+ ;; negative effect on performance is deemed unjustified in
+ ;; this case.
+ (cond (external
+ (funcall external dom))
+ ((fboundp function)
+ (funcall function dom))
+ (t
+ (shr-generic dom)))
+ (when-let ((id (dom-attr dom 'id)))
+ (push (cons id (set-marker (make-marker) start)) shr--link-targets))
+ ;; If style is set, then this node has set the color.
(when style
- (if (string-match-p "color\\|display\\|border-collapse" style)
- (setq shr-stylesheet (nconc (shr-parse-style style)
- shr-stylesheet))
- (setq style nil)))
- ;; If we have a display:none, then just ignore this part of the DOM.
- (unless (or (equal (cdr (assq 'display shr-stylesheet)) "none")
- (and shr-discard-aria-hidden
- (equal (dom-attr dom 'aria-hidden) "true")))
- ;; We don't use shr-indirect-call here, since shr-descend is
- ;; the central bit of shr.el, and should be as fast as
- ;; possible. Having one more level of indirection with its
- ;; negative effect on performance is deemed unjustified in
- ;; this case.
- (cond (external
- (funcall external dom))
- ((fboundp function)
- (funcall function dom))
- (t
- (shr-generic dom)))
- (when-let ((id (dom-attr dom 'id)))
- (push (cons id (set-marker (make-marker) start)) shr--link-targets))
- ;; If style is set, then this node has set the color.
- (when style
- (shr-colorize-region
- start (point)
- (cdr (assq 'color shr-stylesheet))
- (cdr (assq 'background-color shr-stylesheet))))))))
+ (shr-colorize-region
+ start (point)
+ (cdr (assq 'color shr-stylesheet))
+ (cdr (assq 'background-color shr-stylesheet)))))))
(defun shr-fill-text (text)
(if (zerop (length text))
@@ -1019,6 +1016,8 @@ the mouse click event."
(widen)
(let ((alt (buffer-substring start end))
(properties (text-properties-at start))
+ ;; We don't want to record these changes.
+ (buffer-undo-list t)
(inhibit-read-only t))
(delete-region start end)
(goto-char start)
@@ -1216,6 +1215,7 @@ START, and END. Note that START and END should be markers."
(add-text-properties
start (point)
(list 'shr-url url
+ 'shr-tab-stop t
'button t
'category 'shr ; For button.el button buffers.
'help-echo (let ((parsed (url-generic-parse-url
@@ -1487,7 +1487,9 @@ ones, in case fg and bg are nil."
(dom-attr dom 'name)))) ; Obsolete since HTML5.
(push (cons id (set-marker (make-marker) start)) shr--link-targets))
(when url
- (shr-urlify (or shr-start start) (shr-expand-url url) title)
+ (shr-urlify (or shr-start start)
+ (funcall shr-url-transformer (shr-expand-url url))
+ title)
;; Check whether the URL is suspicious.
(when-let ((warning (or (textsec-suspicious-p
(shr-expand-url url) 'url)
diff --git a/lisp/net/sieve-mode.el b/lisp/net/sieve-mode.el
index f62af03534a..695a3235a7b 100644
--- a/lisp/net/sieve-mode.el
+++ b/lisp/net/sieve-mode.el
@@ -200,7 +200,13 @@ Turning on Sieve mode runs `sieve-mode-hook'."
(let ((depth (car (syntax-ppss))))
(when (looking-at "[ \t]*}")
(setq depth (1- depth)))
- (indent-line-to (* 2 depth)))))
+ (indent-line-to (* 2 depth))))
+ ;; Skip to the end of the indentation if at the beginning of the
+ ;; line.
+ (when (save-excursion
+ (skip-chars-backward " \t")
+ (bolp))
+ (skip-chars-forward " \t")))
(provide 'sieve-mode)
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 9ff5d6ac75d..646ae864526 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -112,8 +112,10 @@
(eval-when-compile (require 'cl-lib))
;; Sometimes, compilation fails with "Variable binding depth exceeds
;; max-specpdl-size". Shall be fixed in Emacs 27.
-(eval-and-compile
- (let ((max-specpdl-size (* 2 max-specpdl-size))) (require 'tramp-gvfs)))
+(with-no-warnings ;; max-specpdl-size
+ (eval-and-compile
+ (let ((max-specpdl-size (* 2 max-specpdl-size)))
+ (require 'tramp-gvfs))))
(autoload 'dired-uncache "dired")
(autoload 'url-tramp-convert-url-to-tramp "url-tramp")
@@ -199,7 +201,7 @@ It must be supported by libarchive(3).")
(put #'tramp-archive-autoload-file-name-regexp 'tramp-autoload t)
-;; In older Emacsen (prior 27.1), `tramp-archive-autoload-file-name-regexp'
+;; In older Emacs (prior 27.1), `tramp-archive-autoload-file-name-regexp'
;; is not autoloaded. So we cannot expect it to be known in
;; tramp-loaddefs.el. But it exists, when tramp-archive.el is loaded.
;;;###tramp-autoload
@@ -330,7 +332,7 @@ arguments to pass to the OPERATION."
;; Starting with Emacs 29, `tramp-archive-file-name-handler' is
;; autoloaded. But it must still be in tramp-loaddefs.el for older
-;; Emacsen.
+;; versions of Emacs.
;;;###autoload(autoload 'tramp-archive-file-name-handler "tramp-archive")
;;;###tramp-autoload
(defun tramp-archive-file-name-handler (operation &rest args)
@@ -343,6 +345,7 @@ arguments to pass to the OPERATION."
(tramp-register-file-name-handlers)
(tramp-archive-run-real-handler operation args))
+ (with-no-warnings ;; max-specpdl-size
(let* ((filename (apply #'tramp-archive-file-name-for-operation
operation args))
(archive (tramp-archive-file-name-archive filename))
@@ -376,7 +379,7 @@ arguments to pass to the OPERATION."
(setq args (cons operation args)))
(if fn
(save-match-data (apply (cdr fn) args))
- (tramp-archive-run-real-handler operation args)))))))
+ (tramp-archive-run-real-handler operation args))))))))
;;;###autoload
(progn (defun tramp-archive-autoload-file-name-handler (operation &rest args)
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index 58954c238e0..4d7d35a4de6 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -28,7 +28,7 @@
;; An implementation of information caching for remote files.
;; Each connection, identified by a `tramp-file-name' structure or by
-;; a process, has a unique cache. We distinguish 5 kind of caches,
+;; a process, has a unique cache. We distinguish 6 kind of caches,
;; depending on the key:
;;
;; - localname is nil. These are reusable properties. Examples:
@@ -43,8 +43,7 @@
;; existence, or "file-attributes" caches the result of the function
;; `file-attributes'. These entries have a timestamp, and they
;; expire after `remote-file-name-inhibit-cache' seconds if this
-;; variable is set. These properties are taken into account only if
-;; the connection is established, or `non-essential' is nil.
+;; variable is set.
;;
;; - The key is a process. These are temporary properties related to
;; an open connection. Examples: "scripts" keeps shell script
@@ -57,6 +56,10 @@
;; "{uid,gid}-{integer,string}" are the local uid and gid, and
;; "locale" is the used shell locale.
;;
+;; - The key is `tramp-cache-version'. It keeps the Tramp version the
+;; cache data was produced with. If the cache is read by another
+;; Tramp version, it is flushed.
+;;
;; - The key is `tramp-cache-undefined'. All functions return the
;; expected values, but nothing is cached.
@@ -106,6 +109,10 @@ details see the info pages."
:group 'tramp
:type 'file)
+;;;###tramp-autoload
+(defconst tramp-cache-version (make-tramp-file-name :method "cache")
+"Virtual connection vector for Tramp version.")
+
(defvar tramp-cache-data-changed nil
"Whether persistent cache data have been changed.")
@@ -633,9 +640,16 @@ for all methods. Resulting data are derived from connection history."
;; initialized properly by side effect.
(unless (tramp-connection-property-p key (car item))
(tramp-set-connection-property key (pop item) (car item)))))))
+ ;; Check Tramp version. Clear cache in case of mismatch.
+ (unless (string-equal
+ (tramp-get-connection-property
+ tramp-cache-version "tramp-version" "")
+ tramp-version)
+ (signal 'file-error nil))
(setq tramp-cache-data-changed nil))
(file-error
- ;; Most likely because the file doesn't exist yet. No message.
+ ;; Most likely because the file doesn't exist yet, or the Tramp
+ ;; version doesn't match. No message.
(clrhash tramp-cache-data))
(error
;; File is corrupted.
@@ -643,6 +657,9 @@ for all methods. Resulting data are derived from connection history."
tramp-persistency-file-name (error-message-string err))
(clrhash tramp-cache-data))))
+;; Initialize the cache version.
+(tramp-set-connection-property tramp-cache-version "tramp-version" tramp-version)
+
(add-hook 'tramp-unload-hook
(lambda ()
(unload-feature 'tramp-cache 'force)))
diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el
index d36514bab26..0442fa74096 100644
--- a/lisp/net/tramp-cmds.el
+++ b/lisp/net/tramp-cmds.el
@@ -179,6 +179,10 @@ This includes password cache, file cache, connection cache, buffers."
;; Flush file and connection cache.
(clrhash tramp-cache-data)
+ ;; Initialize the cache version.
+ (tramp-set-connection-property
+ tramp-cache-version "tramp-version" tramp-version)
+
;; Remove ad-hoc proxies.
(let ((proxies tramp-default-proxies-alist))
(while proxies
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index aae15fafdf2..a1d1d284edb 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -36,6 +36,7 @@
(require 'shell)
(require 'subr-x)
+(declare-function tramp-compat-rx "tramp")
(declare-function tramp-error "tramp")
(declare-function tramp-file-name-handler "tramp")
(declare-function tramp-tramp-file-p "tramp")
@@ -49,6 +50,13 @@
(warn "Tramp has been compiled with Emacs %s, this is Emacs %s"
tramp-compat-emacs-compiled-version emacs-version))
+(with-eval-after-load 'docker-tramp
+ (warn (concat "Package `docker-tramp' has been obsoleted, "
+ "please use integrated package `tramp-container'")))
+(with-eval-after-load 'kubernetes-tramp
+ (warn (concat "Package `kubernetes-tramp' has been obsoleted, "
+ "please use integrated package `tramp-container'")))
+
;; For not existing functions, obsolete functions, or functions with a
;; changed argument list, there are compiler warnings. We want to
;; avoid them in cases we know what we do.
diff --git a/lisp/net/tramp-container.el b/lisp/net/tramp-container.el
new file mode 100644
index 00000000000..e104babed27
--- /dev/null
+++ b/lisp/net/tramp-container.el
@@ -0,0 +1,190 @@
+;;; tramp-container.el --- Tramp integration for Docker-like containers -*- lexical-binding: t; -*-
+
+;; Copyright © 2022 Free Software Foundation, Inc.
+
+;; Author: Brian Cully <bjc@kublai.com>
+;; Keywords: comm, processes
+;; Package: tramp
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Allows Tramp access to environments provided by Docker and similar
+;; programs.
+;;
+;; ## Usage
+;;
+;; Open a file on a running Docker container:
+;;
+;; C-x C-f /docker:USER@CONTAINER:/path/to/file
+;;
+;; or Podman:
+;;
+;; C-x C-f /podman:USER@CONTAINER:/path/to/file
+;;
+;; Where:
+;; USER is the user on the container to connect as (optional)
+;; CONTAINER is the container to connect to
+;;
+;;
+;; Open file in a Kubernetes container:
+;;
+;; C-x C-f /kubernetes:POD:/path/to/file
+;;
+;; Where:
+;; POD is the pod to connect to.
+;; By default, the first container in that pod will be
+;; used.
+;;
+;; Completion for POD and accessing it operate in the current
+;; namespace, use this command to change it:
+;;
+;; "kubectl config set-context --current --namespace=<name>"
+
+;;; Code:
+
+(require 'tramp)
+
+;;;###tramp-autoload
+(defcustom tramp-docker-program "docker"
+ "Name of the Docker client program."
+ :group 'tramp
+ :version "29.1"
+ :type '(choice (const "docker")
+ (string)))
+
+;;;###tramp-autoload
+(defcustom tramp-podman-program "podman"
+ "Name of the Podman client program."
+ :group 'tramp
+ :version "29.1"
+ :type '(choice (const "podman")
+ (string)))
+
+;;;###tramp-autoload
+(defcustom tramp-kubernetes-program "kubectl"
+ "Name of the Kubernetes client program."
+ :group 'tramp
+ :version "29.1"
+ :type '(choice (const "kubectl")
+ (string)))
+
+;;;###tramp-autoload
+(defconst tramp-docker-method "docker"
+ "Tramp method name to use to connect to Docker containers.")
+
+;;;###tramp-autoload
+(defconst tramp-podman-method "podman"
+ "Tramp method name to use to connect to Podman containers.")
+
+;;;###tramp-autoload
+(defconst tramp-kubernetes-method "kubernetes"
+ "Tramp method name to use to connect to Kubernetes containers.")
+
+;;;###tramp-autoload
+(defun tramp-docker--completion-function (&rest _args)
+ "List Docker-like containers available for connection.
+
+This function is used by `tramp-set-completion-function', please
+see its function help for a description of the format."
+ (when-let ((raw-list (shell-command-to-string
+ (concat tramp-docker-program
+ " ps --format '{{.ID}}\t{{.Names}}'")))
+ (lines (split-string raw-list "\n" 'omit))
+ (names (mapcar
+ (lambda (line)
+ (when (string-match
+ (rx bol (group (1+ nonl))
+ "\t" (? (group (1+ nonl))) eol)
+ line)
+ (or (match-string 2 line) (match-string 1 line))))
+ lines)))
+ (mapcar (lambda (m) (list nil m)) (delq nil names))))
+
+;;;###tramp-autoload
+(defun tramp-kubernetes--completion-function (&rest _args)
+ "List Kubernetes pods available for connection.
+
+This function is used by `tramp-set-completion-function', please
+see its function help for a description of the format."
+ (when-let ((raw-list (shell-command-to-string
+ (concat tramp-kubernetes-program
+ " get pods --no-headers "
+ "-o custom-columns=NAME:.metadata.name")))
+ (names (split-string raw-list "\n" 'omit)))
+ (mapcar (lambda (name)
+ (list nil name))
+ names)))
+
+;;;###tramp-autoload
+(defvar tramp-default-remote-shell) ;; Silence byte compiler.
+
+;;;###tramp-autoload
+(tramp--with-startup
+ (add-to-list 'tramp-methods
+ `(,tramp-docker-method
+ (tramp-login-program ,tramp-docker-program)
+ (tramp-login-args (("exec")
+ ("-it")
+ ("-u" "%u")
+ ("%h")
+ ("%l")))
+ (tramp-remote-shell ,tramp-default-remote-shell)
+ (tramp-remote-shell-login ("-l"))
+ (tramp-remote-shell-args ("-i" "-c"))))
+ (add-to-list 'tramp-methods
+ `(,tramp-podman-method
+ (tramp-login-program ,tramp-podman-program)
+ (tramp-login-args (("exec")
+ ("-it")
+ ("-u" "%u")
+ ("%h")
+ ("%l")))
+ (tramp-remote-shell ,tramp-default-remote-shell)
+ (tramp-remote-shell-login ("-l"))
+ (tramp-remote-shell-args ("-i" "-c"))))
+ (add-to-list 'tramp-methods
+ `(,tramp-kubernetes-method
+ (tramp-login-program ,tramp-kubernetes-program)
+ (tramp-login-args (("exec")
+ ("%h")
+ ("-it")
+ ("--")
+ ("%l")))
+ (tramp-remote-shell ,tramp-default-remote-shell)
+ (tramp-remote-shell-login ("-l"))
+ (tramp-remote-shell-args ("-i" "-c"))))
+
+ (tramp-set-completion-function
+ tramp-docker-method
+ '((tramp-docker--completion-function "")))
+
+ (tramp-set-completion-function
+ tramp-podman-method
+ '((tramp-docker--completion-function "")))
+
+ (tramp-set-completion-function
+ tramp-kubernetes-method
+ '((tramp-kubernetes--completion-function ""))))
+
+(add-hook 'tramp-unload-hook
+ (lambda ()
+ (unload-feature 'tramp-container 'force)))
+
+(provide 'tramp-container)
+
+;;; tramp-container.el ends here
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el
index d556c876066..16c4049a687 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -852,6 +852,14 @@ WILDCARD is not supported."
(tramp-compat-funcall
'unlock-file (tramp-crypt-encrypt-file-name filename))))
+(with-eval-after-load 'bookmark
+ (add-hook 'bookmark-inhibit-context-functions
+ #'tramp-crypt-file-name-p)
+ (add-hook 'tramp-crypt-unload-hook
+ (lambda ()
+ (remove-hook 'bookmark-inhibit-context-functions
+ #'tramp-crypt-file-name-p))))
+
(add-hook 'tramp-unload-hook
(lambda ()
(unload-feature 'tramp-crypt 'force)))
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index cf23676b0c2..477f8fb3fdd 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -2505,6 +2505,7 @@ This uses \"avahi-browse\" in case D-Bus is not enabled in Avahi."
result))))
(when tramp-gvfs-enabled
+ (with-no-warnings ;; max-specpdl-size
;; Suppress D-Bus error messages and Tramp traces.
(let (;; Sometimes, it fails with "Variable binding depth exceeds
;; max-specpdl-size". Shall be fixed in Emacs 27.
@@ -2562,7 +2563,7 @@ This uses \"avahi-browse\" in case D-Bus is not enabled in Avahi."
"mtp"
(mapcar
(lambda (method) `(tramp-parse-media-names ,(format "_%s._tcp" method)))
- tramp-media-methods))))
+ tramp-media-methods)))))
(add-hook 'tramp-unload-hook
(lambda ()
diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el
index 61b2c2ecb7c..35c0636b1cc 100644
--- a/lisp/net/tramp-integration.el
+++ b/lisp/net/tramp-integration.el
@@ -130,8 +130,10 @@ been set up by `rfn-eshadow-setup-minibuffer'."
;; Remove last element of `(exec-path)', which is `exec-directory'.
;; Use `path-separator' as it does eshell.
(setq eshell-path-env
- (mapconcat
- #'identity (butlast (tramp-compat-exec-path)) path-separator)))
+ (if (file-remote-p default-directory)
+ (mapconcat
+ #'identity (butlast (tramp-compat-exec-path)) path-separator)
+ (getenv "PATH"))))
(with-eval-after-load 'esh-util
(add-hook 'eshell-mode-hook
@@ -217,12 +219,12 @@ NAME must be equal to `tramp-current-connection'."
(info-lookup-maybe-add-help
:mode 'tramp-info-lookup-mode :topic 'symbol
:regexp (rx (+ (not (any "\t\n \"'(),[]`‘’"))))
- :doc-spec '(("(tramp)Function Index" nil
- (rx bol blank (+ "-") blank (* nonl) ": ")
- (rx (| blank eol)))
+ :doc-spec `(("(tramp)Function Index" nil
+ ,(rx bol blank (+ "-") blank (* nonl) ":" blank)
+ ,(rx (| blank eol)))
("(tramp)Variable Index" nil
- (rx bol blank (+ "-") blank (* nonl) ": ")
- (rx (| blank eol)))))
+ ,(rx bol blank (+ "-") blank (* nonl) ":" blank)
+ ,(rx (| blank eol)))))
(add-hook
'tramp-integration-unload-hook
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 1c26e25e57e..d74afc84126 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -789,8 +789,8 @@ use strict;
use warnings;
use POSIX qw(getgroups);
-my ($user, $passwd, $uid, $gid) = getpwuid $< ;
-my $group = getgrgid $gid ;
+my ( $uid, $user ) = ( $>, scalar getpwuid $> );
+my ( $gid, $group ) = ( $), scalar getgrgid $) );
my @groups = map { $_ . \"(\" . getgrgid ($_) . \")\" } getgroups ();
printf \"uid=%%d(%%s) gid=%%d(%%s) groups=%%s\\n\",
@@ -1528,7 +1528,7 @@ of."
time)))
(tramp-send-command-and-check
v (format
- "env TZ=UTC %s %s %s %s"
+ "env TZ=UTC0 %s %s %s %s"
(tramp-get-remote-touch v)
(if (tramp-get-connection-property v "touch-t")
(format "-t %s" (format-time-string "%Y%m%d%H%M.%S" time t))
@@ -2827,11 +2827,14 @@ the result will be a local, non-Tramp, file name."
;; Handle empty NAME.
(when (zerop (length name)) (setq name "."))
;; On MS Windows, some special file names are not returned properly
- ;; by `file-name-absolute-p'.
- (if (and (eq system-type 'windows-nt)
- (string-match-p
- (tramp-compat-rx bol (| (: alpha ":") (: (literal null-device) eol)))
- name))
+ ;; by `file-name-absolute-p'. If `tramp-syntax' is `simplified',
+ ;; there could be the falso positive "/:".
+ (if (or (and (eq system-type 'windows-nt)
+ (string-match-p
+ (tramp-compat-rx bol (| (: alpha ":") (: (literal null-device) eol)))
+ name))
+ (and (not (tramp-tramp-file-p name))
+ (not (tramp-tramp-file-p dir))))
(tramp-run-real-handler #'expand-file-name (list name dir))
;; Unless NAME is absolute, concat DIR and NAME.
(unless (file-name-absolute-p name)
@@ -3814,6 +3817,7 @@ Fall back to normal file name handler if no Tramp handler exists."
(concat "create,modify,move,moved_from,moved_to,move_self,"
"delete,delete_self,ignored"))
((memq 'attribute-change flags) "attrib,ignored"))
+ ;; "-P" has been added to version 3.21, so we cannot assume it yet.
sequence `(,command "-mq" "-e" ,events ,localname)
;; Make events a list of symbols.
events
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 11b3689df60..e55f6bb6ee5 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -1761,7 +1761,7 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)."
;;
;; Problems:
;; * Modern regexp constructs, like spy groups and counted repetitions, aren't
-;; available in older Emacsen.
+;; available in older versions of Emacs.
;; * The length of constructs (file name, size) might exceed the default.
;; * File names might contain spaces.
;; * Permissions might be empty.
diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el
index b89e1282d21..3c67fa6ea2f 100644
--- a/lisp/net/tramp-sshfs.el
+++ b/lisp/net/tramp-sshfs.el
@@ -47,6 +47,9 @@
:type 'string)
;;;###tramp-autoload
+(defvar tramp-default-remote-shell) ;; Silence byte compiler.
+
+;;;###tramp-autoload
(tramp--with-startup
(add-to-list 'tramp-methods
`(,tramp-sshfs-method
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index f8b602e34ce..bc8739c4d6c 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -369,33 +369,36 @@ the result will be a local, non-Tramp, file name."
;; Unless NAME is absolute, concat DIR and NAME.
(unless (file-name-absolute-p name)
(setq name (tramp-compat-file-name-concat dir name)))
- (with-parsed-tramp-file-name name nil
- ;; Tilde expansion if necessary. We cannot accept "~/", because
- ;; under sudo "~/" is expanded to the local user home directory
- ;; but to the root home directory.
- (when (zerop (length localname))
- (setq localname "~"))
- (unless (file-name-absolute-p localname)
- (setq localname (format "~%s/%s" user localname)))
- (when (string-match
- (tramp-compat-rx bos "~" (group (* (not "/"))) (group (* nonl)) eos)
- localname)
- (let ((uname (match-string 1 localname))
- (fname (match-string 2 localname))
- hname)
- (when (zerop (length uname))
- (setq uname user))
- (when (setq hname (tramp-get-home-directory v uname))
- (setq localname (concat hname fname)))))
- ;; Do not keep "/..".
- (when (string-match-p (rx bos "/" (** 1 2 ".") eos) localname)
- (setq localname "/"))
- ;; Do normal `expand-file-name' (this does "~user/", "/./" and "/../").
- (tramp-make-tramp-file-name
- v (if (string-prefix-p "~" localname)
- localname
- (tramp-run-real-handler
- #'expand-file-name (list localname))))))
+ ;; If NAME is not a Tramp file, run the real handler.
+ (if (not (tramp-tramp-file-p name))
+ (tramp-run-real-handler #'expand-file-name (list name))
+ (with-parsed-tramp-file-name name nil
+ ;; Tilde expansion if necessary. We cannot accept "~/", because
+ ;; under sudo "~/" is expanded to the local user home directory
+ ;; but to the root home directory.
+ (when (zerop (length localname))
+ (setq localname "~"))
+ (unless (file-name-absolute-p localname)
+ (setq localname (format "~%s/%s" user localname)))
+ (when (string-match
+ (tramp-compat-rx bos "~" (group (* (not "/"))) (group (* nonl)) eos)
+ localname)
+ (let ((uname (match-string 1 localname))
+ (fname (match-string 2 localname))
+ hname)
+ (when (zerop (length uname))
+ (setq uname user))
+ (when (setq hname (tramp-get-home-directory v uname))
+ (setq localname (concat hname fname)))))
+ ;; Do not keep "/..".
+ (when (string-match-p (rx bos "/" (** 1 2 ".") eos) localname)
+ (setq localname "/"))
+ ;; Do normal `expand-file-name' (this does "~user/", "/./" and "/../").
+ (tramp-make-tramp-file-name
+ v (if (string-prefix-p "~" localname)
+ localname
+ (tramp-run-real-handler
+ #'expand-file-name (list localname)))))))
(defun tramp-sudoedit-remote-acl-p (vec)
"Check, whether ACL is enabled on the remote host."
@@ -568,7 +571,7 @@ the result will be a local, non-Tramp, file name."
nil
time)))
(tramp-sudoedit-send-command
- v "env" "TZ=UTC" "touch" "-t"
+ v "env" "TZ=UTC0" "touch" "-t"
(format-time-string "%Y%m%d%H%M.%S" time t)
(if (eq flag 'nofollow) "-h" "")
(tramp-compat-file-name-unquote localname)))))
diff --git a/lisp/net/tramp-uu.el b/lisp/net/tramp-uu.el
index e849c36d132..2bbdb299a69 100644
--- a/lisp/net/tramp-uu.el
+++ b/lisp/net/tramp-uu.el
@@ -25,7 +25,7 @@
;;; Commentary:
;; An implementation of "uuencode" in Lisp. Uses the function
-;; base64-encode-region which is built-in to modern Emacsen.
+;; base64-encode-region which is built-in to modern Emacs.
;;; Code:
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 90cc03c188e..4ff57e5d560 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -205,9 +205,9 @@ pair of the form (KEY VALUE). The following KEYs are defined:
MUST be a Bourne-like shell. It is normally not necessary to
set this to any value other than \"/bin/sh\": Tramp wants to
use a shell which groks tilde expansion, but it can search
- for it. Also note that \"/bin/sh\" exists on all Unixen,
- this might not be true for the value that you decide to use.
- You Have Been Warned.
+ for it. Also note that \"/bin/sh\" exists on all Unixen
+ except Andtoid, this might not be true for the value that you
+ decide to use. You Have Been Warned.
* `tramp-remote-shell-login'
This specifies the arguments to let `tramp-remote-shell' run
@@ -278,7 +278,8 @@ pair of the form (KEY VALUE). The following KEYs are defined:
* `tramp-direct-async'
Whether the method supports direct asynchronous processes.
- Until now, just \"ssh\"-based and \"adb\"-based methods do.
+ Until now, just \"ssh\"-based, \"sshfs\"-based and
+ \"adb\"-based methods do.
* `tramp-copy-program'
This specifies the name of the program to use for remotely copying
@@ -1197,7 +1198,8 @@ The `ftp' syntax does not support methods.")
;; "/ssh:host:~/path" becomes "c:/ssh:host:~/path". See also
;; `tramp-drop-volume-letter'.
(? (regexp tramp-volume-letter-regexp))
- (regexp tramp-prefix-regexp)
+ ;; We cannot use `tramp-prefix-regexp', because it starts with `bol'.
+ (literal tramp-prefix-format)
;; Optional multi hops.
(* (regexp tramp-remote-file-name-spec-regexp)
@@ -1845,7 +1847,8 @@ the form (METHOD USER DOMAIN HOST PORT LOCALNAME &optional HOP)."
tramp-prefix-regexp ""
(replace-regexp-in-string
(tramp-compat-rx
- (regexp tramp-postfix-host-regexp) eos) tramp-postfix-hop-format
+ (regexp tramp-postfix-host-regexp) eos)
+ tramp-postfix-hop-format
(tramp-make-tramp-file-name vec 'noloc)))))
(defun tramp-completion-make-tramp-file-name (method user host localname)
@@ -2860,6 +2863,7 @@ remote file names."
(put #'tramp-completion-file-name-handler 'operations
(mapcar #'car tramp-completion-file-name-handler-alist))
+ ;; Integrated in Emacs 27.
(when (bound-and-true-p tramp-archive-enabled)
(add-to-list 'file-name-handler-alist
(cons tramp-archive-file-name-regexp
@@ -3658,7 +3662,7 @@ Let-bind it when necessary.")
;; `directory-abbrev-apply' and `directory-abbrev-make-regexp' exists
;; since Emacs 29.1. Since this handler isn't called for older
-;; Emacsen, it is save to invoke them via `tramp-compat-funcall'.
+;; Emacs, it is save to invoke them via `tramp-compat-funcall'.
(defun tramp-handle-abbreviate-file-name (filename)
"Like `abbreviate-file-name' for Tramp files."
(let* ((case-fold-search (file-name-case-insensitive-p filename))
@@ -3904,9 +3908,7 @@ Let-bind it when necessary.")
(with-tramp-progress-reporter v 5 "Checking case-insensitive"
;; The idea is to compare a file with lower case
;; letters with the same file with upper case letters.
- (let ((candidate
- (tramp-compat-file-name-unquote
- (directory-file-name filename)))
+ (let ((candidate (directory-file-name filename))
case-fold-search
tmpfile)
;; Check, whether we find an existing file with
@@ -5173,8 +5175,10 @@ of."
;; The descriptor must be a process object.
(unless (processp proc)
(tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc))
- ;; There might be pending output.
- (while (tramp-accept-process-output proc 0))
+ ;; There might be pending output. Avoid problems with reentrant
+ ;; call of Tramp.
+ (ignore-errors
+ (while (tramp-accept-process-output proc 0)))
(tramp-message proc 6 "Kill %S" proc)
(delete-process proc))
@@ -5469,7 +5473,7 @@ performed successfully. Any other value means an error."
Mostly useful to protect BODY from being interrupted by timers."
(declare (indent 1) (debug t))
`(if (tramp-get-connection-property ,proc "locked")
- ;; Be kind for older Emacsen.
+ ;; Be kind for old versions of Emacs.
(if (member 'remote-file-error debug-ignored-errors)
(throw 'non-essential 'non-essential)
(tramp-error
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index dfe5c369e2c..9cbab295042 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -536,8 +536,7 @@ Many aspects this mode can be customized using
(save-restriction
(widen)
(with-silent-modifications
- (nxml-with-invisible-motion
- (nxml-scan-prolog)))))
+ (nxml-scan-prolog))))
(setq-local syntax-ppss-table sgml-tag-syntax-table)
(setq-local syntax-propertize-function #'nxml-syntax-propertize)
(add-function :filter-return (local 'filter-buffer-substring-function)
@@ -584,8 +583,7 @@ Many aspects this mode can be customized using
(save-excursion
(widen)
(with-silent-modifications
- (nxml-with-invisible-motion
- (remove-text-properties (point-min) (point-max) '(face nil)))))
+ (remove-text-properties (point-min) (point-max) '(face nil))))
(remove-hook 'change-major-mode-hook #'nxml-cleanup t))
(defun nxml-degrade (context err)
diff --git a/lisp/nxml/nxml-util.el b/lisp/nxml/nxml-util.el
index 662d43842eb..241c54488fd 100644
--- a/lisp/nxml/nxml-util.el
+++ b/lisp/nxml/nxml-util.el
@@ -65,12 +65,6 @@ This is the inverse of `nxml-make-namespace'."
(nxml-degrade ,context ,error-symbol))))
`(progn ,@body)))
-(defmacro nxml-with-invisible-motion (&rest body)
- "Evaluate body without calling any point motion hooks."
- (declare (indent 0) (debug t))
- `(let ((inhibit-point-motion-hooks t))
- ,@body))
-
(defun nxml-display-file-parse-error (err)
(let* ((filename (nth 1 err))
(buffer (find-file-noselect filename))
diff --git a/lisp/nxml/rng-nxml.el b/lisp/nxml/rng-nxml.el
index ccbf4d8de2e..b1beb195032 100644
--- a/lisp/nxml/rng-nxml.el
+++ b/lisp/nxml/rng-nxml.el
@@ -366,45 +366,44 @@ set `xmltok-dtd'. Returns the position of the end of the token."
(save-excursion
(save-restriction
(widen)
- (nxml-with-invisible-motion
- (if (= pos (point-min))
- (rng-set-initial-state)
- (let ((state (get-text-property (1- pos) 'rng-state)))
- (cond (state
- (rng-restore-state state)
- (goto-char pos))
- (t
- (let ((start (previous-single-property-change pos
- 'rng-state)))
- (cond (start
- (rng-restore-state (get-text-property (1- start)
- 'rng-state))
- (goto-char start))
- (t (rng-set-initial-state))))))))
- (xmltok-save
- (if (= (point) 1)
- (xmltok-forward-prolog)
- (setq xmltok-dtd rng-dtd))
- (cond ((and (< pos (point))
- ;; This handles the case where the prolog ends
- ;; with a < without any following name-start
- ;; character. This will be treated by the parser
- ;; as part of the prolog, but we want to treat
- ;; it as the start of the instance.
- (eq (char-after pos) ?<)
- (<= (point)
- (save-excursion
- (goto-char (1+ pos))
- (skip-chars-forward " \t\r\n")
- (point))))
- pos)
- ((< (point) pos)
- (let ((rng-dt-namespace-context-getter
- '(nxml-ns-get-context))
- (rng-parsing-for-state t))
- (rng-forward pos))
- (point))
- (t pos)))))))
+ (if (= pos (point-min))
+ (rng-set-initial-state)
+ (let ((state (get-text-property (1- pos) 'rng-state)))
+ (cond (state
+ (rng-restore-state state)
+ (goto-char pos))
+ (t
+ (let ((start (previous-single-property-change pos
+ 'rng-state)))
+ (cond (start
+ (rng-restore-state (get-text-property (1- start)
+ 'rng-state))
+ (goto-char start))
+ (t (rng-set-initial-state))))))))
+ (xmltok-save
+ (if (= (point) 1)
+ (xmltok-forward-prolog)
+ (setq xmltok-dtd rng-dtd))
+ (cond ((and (< pos (point))
+ ;; This handles the case where the prolog ends
+ ;; with a < without any following name-start
+ ;; character. This will be treated by the parser
+ ;; as part of the prolog, but we want to treat
+ ;; it as the start of the instance.
+ (eq (char-after pos) ?<)
+ (<= (point)
+ (save-excursion
+ (goto-char (1+ pos))
+ (skip-chars-forward " \t\r\n")
+ (point))))
+ pos)
+ ((< (point) pos)
+ (let ((rng-dt-namespace-context-getter
+ '(nxml-ns-get-context))
+ (rng-parsing-for-state t))
+ (rng-forward pos))
+ (point))
+ (t pos))))))
(defun rng-adjust-state-for-attribute (lt-pos start)
(xmltok-save
diff --git a/lisp/nxml/rng-valid.el b/lisp/nxml/rng-valid.el
index ad5c9c7a15c..d82c8470d75 100644
--- a/lisp/nxml/rng-valid.el
+++ b/lisp/nxml/rng-valid.el
@@ -441,25 +441,24 @@ The schema is set like `rng-auto-set-schema'."
(save-excursion
(save-restriction
(widen)
- (nxml-with-invisible-motion
- (condition-case-unless-debug err
- (and (rng-validate-prepare)
- (let ((rng-dt-namespace-context-getter '(nxml-ns-get-context)))
- (with-silent-modifications
- (rng-do-some-validation-1 continue-p-function))))
- ;; errors signaled from a function run by an idle timer
- ;; are ignored; if we don't catch them, validation
- ;; will get mysteriously stuck at a single place
- (rng-compile-error
- (message "Incorrect schema. %s" (nth 1 err))
- (rng-validate-mode 0)
- nil)
- (error
- (message "Internal error in rng-validate-mode triggered at buffer position %d. %s"
- (point)
- (error-message-string err))
- (rng-validate-mode 0)
- nil))))))
+ (condition-case-unless-debug err
+ (and (rng-validate-prepare)
+ (let ((rng-dt-namespace-context-getter '(nxml-ns-get-context)))
+ (with-silent-modifications
+ (rng-do-some-validation-1 continue-p-function))))
+ ;; errors signaled from a function run by an idle timer
+ ;; are ignored; if we don't catch them, validation
+ ;; will get mysteriously stuck at a single place
+ (rng-compile-error
+ (message "Incorrect schema. %s" (nth 1 err))
+ (rng-validate-mode 0)
+ nil)
+ (error
+ (message "Internal error in rng-validate-mode triggered at buffer position %d. %s"
+ (point)
+ (error-message-string err))
+ (rng-validate-mode 0)
+ nil)))))
(defun rng-validate-prepare ()
"Prepare to do some validation, initializing point and the state.
diff --git a/lisp/linum.el b/lisp/obsolete/linum.el
index 1b897a2bd22..e94cf5086cc 100644
--- a/lisp/linum.el
+++ b/lisp/obsolete/linum.el
@@ -6,6 +6,7 @@
;; Maintainer: emacs-devel@gnu.org
;; Keywords: convenience
;; Old-Version: 0.9x
+;; Obsolete-since: 29.1
;; This file is part of GNU Emacs.
@@ -24,6 +25,13 @@
;;; Commentary:
+;; NOTE: This library was made obsolete in Emacs 29.1. We recommend
+;; using either the built-in `display-line-numbers-mode', or the
+;; `nlinum' package from GNU ELPA instead. The former has better
+;; performance, but the latter is closer to a drop-in replacement.
+;;
+;; --------------------
+;;
;; Display line numbers for the current buffer.
;;
;; Toggle display of line numbers with M-x linum-mode. To enable
@@ -201,10 +209,7 @@ Linum mode is a buffer-local minor mode."
(overlay-put ov 'before-string
(propertize " " 'display `((margin left-margin) ,str)))
(overlay-put ov 'linum-str str))))
- ;; Text may contain those nasty intangible properties, but that
- ;; shouldn't prevent us from counting those lines.
- (let ((inhibit-point-motion-hooks t))
- (forward-line))
+ (forward-line)
(setq line (1+ line)))
(when (display-graphic-p)
(setq width (ceiling
@@ -240,6 +245,9 @@ Linum mode is a buffer-local minor mode."
(defconst linum-version "0.9x")
(make-obsolete-variable 'linum-version 'emacs-version "28.1")
+(make-obsolete 'linum-mode #'display-line-numbers-mode "29.1")
+(make-obsolete 'global-linum-mode #'global-display-line-numbers-mode "29.1")
+
(provide 'linum)
;;; linum.el ends here
diff --git a/lisp/thumbs.el b/lisp/obsolete/thumbs.el
index 0b3d36d6e31..a98b339b470 100644
--- a/lisp/thumbs.el
+++ b/lisp/obsolete/thumbs.el
@@ -5,6 +5,7 @@
;; Author: Jean-Philippe Theberge <jphiltheberge@videotron.ca>
;; Maintainer: emacs-devel@gnu.org
;; Keywords: Multimedia
+;; Obsolete-since: 29.1
;; This file is part of GNU Emacs.
@@ -23,6 +24,11 @@
;;; Commentary:
+;; NOTE: This library was made obsolete in Emacs 29.1.
+;; We recommend using `M-x image-dired' instead.
+;;
+;; --------------------
+;;
;; This package create two new modes: `thumbs-mode' and `thumbs-view-image-mode'.
;; It is used for basic browsing and viewing of images from within Emacs.
;; Minimal image manipulation functions are also available via external
@@ -99,6 +105,8 @@ This must be the ImageMagick \"convert\" utility."
:type 'string
:version "28.1")
+(make-obsolete-variable 'thumbs-setroot-command
+ 'wallpaper-commands-alist "29.1")
(defcustom thumbs-setroot-command
"xloadimage -onroot -fullscreen *"
"Command to set the root window."
@@ -385,6 +393,7 @@ and SAME-WINDOW to show thumbs in the same window."
;;;###autoload
(defalias 'thumbs 'thumbs-show-from-dir)
+(make-obsolete 'thumbs 'image-dired "29.1")
(defun thumbs-find-image (img &optional num otherwin)
(let ((buffer (current-buffer)))
@@ -425,6 +434,7 @@ Open another window."
(defun thumbs-call-setroot-command (img)
"Call the setroot program for IMG."
+ (declare (obsolete wallpaper-set "29.1"))
(run-hooks 'thumbs-before-setroot-hook)
(shell-command (string-replace
"*"
@@ -435,15 +445,13 @@ Open another window."
(defun thumbs-set-image-at-point-to-root-window ()
"Set the image at point as the desktop wallpaper."
(interactive)
- (thumbs-call-setroot-command
- (thumbs-current-image)))
+ (wallpaper-set (thumbs-current-image)))
(defun thumbs-set-root ()
"Set the current image as root."
(interactive)
- (thumbs-call-setroot-command
- (or thumbs-current-tmp-filename
- thumbs-current-image-filename)))
+ (wallpaper-set (or thumbs-current-tmp-filename
+ thumbs-current-image-filename)))
(defun thumbs-file-alist ()
"Make an alist of elements (POS . FILENAME) for all images in thumb buffer."
@@ -756,13 +764,16 @@ ACTION and ARG should be a valid convert command."
(defun thumbs-dired-setroot ()
"In dired, call the setroot program on the image at point."
(interactive)
- (thumbs-call-setroot-command (dired-get-filename)))
+ (wallpaper-set (dired-get-filename)))
;; Modif to dired mode map
(define-key dired-mode-map "\C-ta" 'thumbs-dired-show)
(define-key dired-mode-map "\C-tm" 'thumbs-dired-show-marked)
(define-key dired-mode-map "\C-tw" 'thumbs-dired-setroot)
+(make-obsolete-variable 'thumbs-before-setroot-hook nil "29.1")
+(make-obsolete-variable 'thumbs-after-setroot-hook nil "29.1")
+
(define-obsolete-function-alias 'thumbs-image-type
#'image-supported-file-p "29.1")
diff --git a/lisp/obsolete/vc-arch.el b/lisp/obsolete/vc-arch.el
index 537d65c6587..20835a09d00 100644
--- a/lisp/obsolete/vc-arch.el
+++ b/lisp/obsolete/vc-arch.el
@@ -311,7 +311,7 @@ Only the value `maybe' can be trusted :-(."
;; dir-status-files called from vc-dir, which loads vc,
;; which loads vc-dispatcher.
-(declare-function vc-exec-after "vc-dispatcher" (code))
+(declare-function vc-exec-after "vc-dispatcher" (code &optional success))
(defun vc-arch-dir-status-files (dir _files callback)
"Run `tla inventory' for DIR and pass results to CALLBACK.
diff --git a/lisp/obsolete/vc-mtn.el b/lisp/obsolete/vc-mtn.el
index cd56b290072..4fc496d5095 100644
--- a/lisp/obsolete/vc-mtn.el
+++ b/lisp/obsolete/vc-mtn.el
@@ -141,7 +141,7 @@ switches."
;; dir-status-files called from vc-dir, which loads vc,
;; which loads vc-dispatcher.
-(declare-function vc-exec-after "vc-dispatcher" (code))
+(declare-function vc-exec-after "vc-dispatcher" (code &optional success))
(defun vc-mtn-dir-status-files (dir _files update-function)
(vc-mtn-command (current-buffer) 'async dir "status")
diff --git a/lisp/org/ob-matlab.el b/lisp/org/ob-matlab.el
index 4ee090e4ac7..f50da0ea434 100644
--- a/lisp/org/ob-matlab.el
+++ b/lisp/org/ob-matlab.el
@@ -32,7 +32,7 @@
;; matlab.el required for interactive emacs sessions and matlab-mode
;; major mode for source code editing buffer
-;; http://matlab-emacs.sourceforge.net/
+;; https://matlab-emacs.sourceforge.net/
;;; Code:
(require 'ob)
diff --git a/lisp/org/ob-plantuml.el b/lisp/org/ob-plantuml.el
index ced00fbdda4..7a495e8e7f4 100644
--- a/lisp/org/ob-plantuml.el
+++ b/lisp/org/ob-plantuml.el
@@ -30,7 +30,7 @@
;;; Requirements:
-;; plantuml | http://plantuml.sourceforge.net/
+;; plantuml | https://plantuml.com/
;; plantuml.jar | `org-plantuml-jar-path' should point to the jar file (when exec mode is `jar')
;;; Code:
diff --git a/lisp/org/org-ctags.el b/lisp/org/org-ctags.el
index 6fc97ca399d..67db49e9a67 100644
--- a/lisp/org/org-ctags.el
+++ b/lisp/org/org-ctags.el
@@ -47,7 +47,7 @@
;;
;; Install org mode
;; Ensure org-ctags.el is somewhere in your emacs load path.
-;; Download and install Exuberant ctags -- "http://ctags.sourceforge.net/"
+;; Download and install Exuberant ctags -- "https://ctags.sourceforge.net/"
;; Edit your .emacs file (see next section) and load emacs.
;; To put in your init file (.emacs):
diff --git a/lisp/org/org-macro.el b/lisp/org/org-macro.el
index 0921f3aa27c..b58c51f3fb4 100644
--- a/lisp/org/org-macro.el
+++ b/lisp/org/org-macro.el
@@ -66,7 +66,7 @@
(declare-function org-mode "org" ())
(declare-function vc-backend "vc-hooks" (f))
(declare-function vc-call "vc-hooks" (fun file &rest args) t)
-(declare-function vc-exec-after "vc-dispatcher" (code))
+(declare-function vc-exec-after "vc-dispatcher" (code &optional success))
(defvar org-link-search-must-match-exact-headline)
diff --git a/lisp/org/org-protocol.el b/lisp/org/org-protocol.el
index 7c4de03bc24..7a91a33b745 100644
--- a/lisp/org/org-protocol.el
+++ b/lisp/org/org-protocol.el
@@ -66,7 +66,7 @@
;;
;;
;; As of March 2009 Firefox users follow the steps documented on
-;; http://kb.mozillazine.org/Register_protocol, Opera setup is described here:
+;; https://kb.mozillazine.org/Register_protocol, Opera setup is described here:
;; http://www.opera.com/support/kb/view/535/
;;
;;
diff --git a/lisp/org/org.el b/lisp/org/org.el
index 6f92cdeab5b..7de907590ed 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -5929,10 +5929,7 @@ If TAG is a number, get the corresponding match group."
(defun org-unfontify-region (beg end &optional _maybe_loudly)
"Remove fontification and activation overlays from links."
(font-lock-default-unfontify-region beg end)
- (let* ((buffer-undo-list t)
- (inhibit-read-only t) (inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t)
- deactivate-mark buffer-file-name buffer-file-truename)
+ (with-silent-modifications
(decompose-region beg end)
(remove-text-properties beg end
'(mouse-face t keymap t org-linked-text t
@@ -16702,10 +16699,9 @@ buffer boundaries with possible narrowing."
(defun org-display-inline-remove-overlay (ov after _beg _end &optional _len)
"Remove inline-display overlay if a corresponding region is modified."
- (let ((inhibit-modification-hooks t))
- (when (and ov after)
- (delete ov org-inline-image-overlays)
- (delete-overlay ov))))
+ (when (and ov after)
+ (delete ov org-inline-image-overlays)
+ (delete-overlay ov)))
(defun org-remove-inline-images ()
"Remove inline display of images."
diff --git a/lisp/org/ox.el b/lisp/org/ox.el
index 9a2a69b2c16..56bb4b74df3 100644
--- a/lisp/org/ox.el
+++ b/lisp/org/ox.el
@@ -4642,7 +4642,7 @@ from the export back-end."
;; a given element, excluded. Note: "-n" switches reset that count.
;;
;; `org-export-unravel-code' extracts source code (along with a code
-;; references alist) from an `element-block' or `src-block' type
+;; references alist) from an `example-block' or `src-block' type
;; element.
;;
;; `org-export-format-code' applies a formatting function to each line
diff --git a/lisp/outline.el b/lisp/outline.el
index 6579e12bfed..b87d3ac5e7f 100644
--- a/lisp/outline.el
+++ b/lisp/outline.el
@@ -292,21 +292,66 @@ buffers (yet) -- that will be amended in a future version."
:safe #'booleanp
:version "29.1")
-(define-icon outline-open button
- '((emoji "🔽")
+(defvar-local outline--use-buttons nil
+ "Non-nil when buffer displays clickable buttons on the headings.")
+
+(defvar-local outline--use-rtl nil
+ "Non-nil when direction of clickable buttons is right-to-left.")
+
+(defcustom outline-minor-mode-use-margins '(and (derived-mode . special-mode)
+ (not (derived-mode . help-mode)))
+ "Whether to display clickable buttons in the margins.
+The value should be a `buffer-match-p' condition.
+
+These buttons can be used to hide and show the body under the heading.
+Note that this feature is meant to be used in editing buffers."
+ :type 'buffer-predicate
+ :safe #'booleanp
+ :version "29.1")
+
+(defvar-local outline--use-margins nil
+ "Non-nil when buffer displays clickable buttons in the margins.")
+
+(define-icon outline-open nil
+ '((image "outline-open.svg" "outline-open.pbm" :height (0.8 . em))
+ (emoji "🔽")
(symbol " ▼ ")
(text " open "))
- "Icon used for buttons for opening a section in outline buffers."
+ "Icon used for buttons for opened sections in outline buffers."
:version "29.1"
- :help-echo "Open this section")
+ :help-echo "Close this section")
-(define-icon outline-close button
- '((emoji "▶️")
+(define-icon outline-close nil
+ '((image "outline-close.svg" "outline-close.pbm" :height (0.8 . em))
+ (emoji "▶️")
(symbol " ▶ ")
(text " close "))
- "Icon used for buttons for closing a section in outline buffers."
+ "Icon used for buttons for closed sections in outline buffers."
:version "29.1"
- :help-echo "Close this section")
+ :help-echo "Open this section")
+
+(define-icon outline-close-rtl outline-close
+ '((image "outline-close.svg" "outline-close.pbm" :height (0.8 . em)
+ :rotation 180)
+ (emoji "◀️")
+ (symbol " ◀ "))
+ "Right-to-left icon used for buttons in closed outline sections."
+ :version "29.1")
+
+(define-icon outline-open-in-margins outline-open
+ '((image "outline-open.svg" "outline-open.pbm" :height 10))
+ "Icon used for buttons for opened sections in margins."
+ :version "29.1")
+
+(define-icon outline-close-in-margins outline-close
+ '((image "outline-open.svg" "outline-open.pbm" :height 10 :rotation -90))
+ "Icon used for buttons for closed sections in margins."
+ :version "29.1")
+
+(define-icon outline-close-rtl-in-margins outline-close-rtl
+ '((image "outline-open.svg" "outline-open.pbm" :height 10 :rotation 90))
+ "Right-to-left icon used for closed sections in margins."
+ :version "29.1")
(defvar outline-level #'outline-level
@@ -337,6 +382,10 @@ data reflects the `outline-regexp'.")
:safe #'booleanp
:version "22.1")
+(defvar outline-imenu-generic-expression
+ (list (list nil (concat "^\\(?:" outline-regexp "\\).*$") 0))
+ "Value for `imenu-generic-expression' in Outline mode.")
+
;;;###autoload
(define-derived-mode outline-mode text-mode "Outline"
"Set major mode for editing outlines with selective display.
@@ -371,8 +420,7 @@ Turning on outline mode calls the value of `text-mode-hook' and then of
(concat paragraph-separate "\\|\\(?:" outline-regexp "\\)"))
(setq-local font-lock-defaults
'(outline-font-lock-keywords t nil nil backward-paragraph))
- (setq-local imenu-generic-expression
- (list (list nil (concat "^\\(?:" outline-regexp "\\).*$") 0)))
+ (setq-local imenu-generic-expression outline-imenu-generic-expression)
(add-hook 'change-major-mode-hook #'outline-show-all nil t)
(add-hook 'hack-local-variables-hook #'outline-apply-default-state nil t))
@@ -432,9 +480,7 @@ outline font-lock faces to those of major mode."
(when (or (memq outline-minor-mode-highlight '(append override))
(and (eq outline-minor-mode-highlight t)
(not (get-text-property (match-beginning 0) 'face))))
- (overlay-put overlay 'face (outline-font-lock-face)))
- (when (outline--use-buttons-p)
- (outline--insert-open-button)))
+ (overlay-put overlay 'face (outline-font-lock-face))))
(goto-char (match-end 0))))))
;;;###autoload
@@ -446,16 +492,38 @@ See the command `outline-mode' for more information on this mode."
:keymap (define-keymap
:parent outline-minor-mode-cycle-map
"<menu-bar>" outline-minor-mode-menu-bar-map
+ "<left-margin> <mouse-1>" 'outline-cycle
+ "<right-margin> <mouse-1>" 'outline-cycle
+ "<left-margin> S-<mouse-1>" 'outline-cycle-buffer
+ "<right-margin> S-<mouse-1>" 'outline-cycle-buffer
(key-description outline-minor-mode-prefix) outline-mode-prefix-map)
(if outline-minor-mode
(progn
+ (cond
+ ((buffer-match-p outline-minor-mode-use-margins (current-buffer))
+ (setq-local outline--use-margins t))
+ ((buffer-match-p outline-minor-mode-use-buttons (current-buffer))
+ (setq-local outline--use-buttons t)))
+ (when (and (or outline--use-buttons outline--use-margins)
+ (eq (current-bidi-paragraph-direction) 'right-to-left))
+ (setq-local outline--use-rtl t))
+ (when outline--use-margins
+ (if outline--use-rtl
+ (setq-local right-margin-width (1+ right-margin-width))
+ (setq-local left-margin-width (1+ left-margin-width)))
+ (setq-local fringes-outside-margins t)
+ ;; Force display of margins
+ (set-window-buffer nil (window-buffer)))
+ (when (or outline--use-buttons outline--use-margins)
+ (add-hook 'after-change-functions
+ #'outline--fix-buttons-after-change nil t))
(when outline-minor-mode-highlight
(if (and global-font-lock-mode (font-lock-specified-p major-mode))
(progn
(font-lock-add-keywords nil outline-font-lock-keywords t)
- (font-lock-flush)
- (outline--fix-up-all-buttons))
+ (font-lock-flush))
(outline-minor-mode-highlight-buffer)))
+ (outline--fix-up-all-buttons)
;; Turn off this mode if we change major modes.
(add-hook 'change-major-mode-hook
(lambda () (outline-minor-mode -1))
@@ -464,20 +532,26 @@ See the command `outline-mode' for more information on this mode."
;; Cause use of ellipses for invisible text.
(add-to-invisibility-spec '(outline . t))
(outline-apply-default-state))
- (when outline-minor-mode-highlight
- (if font-lock-fontified
- (font-lock-remove-keywords nil outline-font-lock-keywords))
- (remove-overlays nil nil 'outline-overlay t)
- (font-lock-flush))
(setq line-move-ignore-invisible nil)
;; Cause use of ellipses for invisible text.
(remove-from-invisibility-spec '(outline . t))
;; When turning off outline mode, get rid of any outline hiding.
- (outline-show-all)))
-
-(defun outline--use-buttons-p ()
- (and outline-minor-mode
- (buffer-match-p outline-minor-mode-use-buttons (current-buffer))))
+ (outline-show-all)
+ (when outline-minor-mode-highlight
+ (if font-lock-fontified
+ (font-lock-remove-keywords nil outline-font-lock-keywords))
+ (font-lock-flush)
+ (remove-overlays nil nil 'outline-overlay t))
+ (when outline--use-buttons
+ (remove-overlays nil nil 'outline-button t))
+ (when outline--use-margins
+ (remove-overlays nil nil 'outline-margin t)
+ (if outline--use-rtl
+ (setq-local right-margin-width (1- right-margin-width))
+ (setq-local left-margin-width (1- left-margin-width)))
+ (setq-local fringes-outside-margins nil)
+ ;; Force removal of margins
+ (set-window-buffer nil (window-buffer)))))
(defvar-local outline-heading-alist ()
"Alist associating a heading for every possible level.
@@ -980,81 +1054,10 @@ Note that this does not hide the lines preceding the first heading line."
"Hide everything after this heading at deeper levels.
If non-nil, EVENT should be a mouse event."
(interactive (list last-nonmenu-event))
- (when (mouse-event-p event)
- (mouse-set-point event))
- (when (outline--use-buttons-p)
- (outline--insert-close-button))
- (outline-flag-subtree t))
-
-(defun outline--make-button-overlay (type)
- (let ((o (seq-find (lambda (o)
- (overlay-get o 'outline-button))
- (overlays-at (point)))))
- (unless o
- (setq o (make-overlay (point) (1+ (point))))
- (overlay-put o 'follow-link 'mouse-face)
- (overlay-put o 'mouse-face 'highlight)
- (overlay-put o 'outline-button t))
- (let ((icon
- (icon-elements (if (eq type 'close) 'outline-close 'outline-open)))
- (inhibit-read-only t))
- ;; In editing buffers we use overlays only, but in other buffers
- ;; we use a mix of text properties, text and overlays to make
- ;; movement commands work more logically.
- (when (derived-mode-p 'special-mode)
- (put-text-property (point) (1+ (point)) 'face (plist-get icon 'face)))
- (when-let ((image (plist-get icon 'image)))
- (overlay-put o 'display image))
- (overlay-put o 'display (concat (plist-get icon 'string)
- (string (char-after (point)))))
- (overlay-put o 'face (plist-get icon 'face)))
- o))
-
-(defun outline--insert-open-button ()
- (with-silent-modifications
- (save-excursion
- (beginning-of-line)
- (when (derived-mode-p 'special-mode)
- (let ((inhibit-read-only t))
- (insert " ")
- (beginning-of-line)))
- (let ((o (outline--make-button-overlay 'open)))
- (overlay-put o 'help-echo "Click to hide")
- (overlay-put o 'keymap
- (define-keymap
- "RET" #'outline-hide-subtree
- "<mouse-2>" #'outline-hide-subtree))))))
-
-(defun outline--insert-close-button ()
- (with-silent-modifications
- (save-excursion
- (beginning-of-line)
- (when (derived-mode-p 'special-mode)
- (let ((inhibit-read-only t))
- (insert " ")
- (beginning-of-line)))
- (let ((o (outline--make-button-overlay 'close)))
- (overlay-put o 'help-echo "Click to show")
- (overlay-put o 'keymap
- (define-keymap
- "RET" #'outline-show-subtree
- "<mouse-2>" #'outline-show-subtree))))))
-
-(defun outline--fix-up-all-buttons (&optional from to)
- (when from
- (save-excursion
- (goto-char from)
- (setq from (line-beginning-position))))
- (when (outline--use-buttons-p)
- (outline-map-region
- (lambda ()
- ;; `outline--cycle-state' will fail if we're in a totally
- ;; collapsed buffer -- but in that case, we're not in a
- ;; `show-all' situation.
- (if (eq (ignore-errors (outline--cycle-state)) 'show-all)
- (outline--insert-open-button)
- (outline--insert-close-button)))
- (or from (point-min)) (or to (point-max)))))
+ (save-excursion
+ (when (mouse-event-p event)
+ (mouse-set-point event))
+ (outline-flag-subtree t)))
(define-obsolete-function-alias 'hide-subtree #'outline-hide-subtree "25.1")
@@ -1072,13 +1075,13 @@ If non-nil, EVENT should be a mouse event."
(define-obsolete-function-alias 'hide-leaves #'outline-hide-leaves "25.1")
(defun outline-show-subtree (&optional event)
- "Show everything after this heading at deeper levels."
+ "Show everything after this heading at deeper levels.
+If non-nil, EVENT should be a mouse event."
(interactive (list last-nonmenu-event))
- (when (mouse-event-p event)
- (mouse-set-point event))
- (when (outline--use-buttons-p)
- (outline--insert-open-button))
- (outline-flag-subtree nil))
+ (save-excursion
+ (when (mouse-event-p event)
+ (mouse-set-point event))
+ (outline-flag-subtree nil)))
(define-obsolete-function-alias 'show-subtree #'outline-show-subtree "25.1")
@@ -1341,6 +1344,9 @@ convenient way to make a table of contents of the buffer."
(insert "\n\n"))))))
(kill-new (buffer-string)))))))
+
+;;; Initial visibility
+
(defcustom outline-default-state nil
"If non-nil, some headings are initially outlined.
@@ -1519,6 +1525,9 @@ LEVEL, decides of subtree visibility according to
beg end)))
(run-hooks 'outline-view-change-hook)))
+
+;;; Visibility cycling
+
(defun outline--cycle-state ()
"Return the cycle state of current heading.
Return either `hide-all', `headings-only', or `show-all'."
@@ -1553,7 +1562,7 @@ Return either `hide-all', `headings-only', or `show-all'."
(< (save-excursion (outline-next-heading) (point))
(save-excursion (outline-end-of-subtree) (point)))))
-(defun outline-cycle ()
+(defun outline-cycle (&optional event)
"Cycle visibility state of the current heading line's body.
This cycles the visibility of the current heading line's subheadings
@@ -1561,23 +1570,28 @@ and body between `hide all', `headings only' and `show all'.
`Hide all' means hide all the subheadings and their bodies.
`Headings only' means show the subheadings, but not their bodies.
-`Show all' means show all the subheadings and their bodies."
- (interactive)
- (condition-case nil
- (pcase (outline--cycle-state)
- ('hide-all
- (if (outline-has-subheading-p)
- (progn (outline-show-children)
- (message "Only headings"))
+`Show all' means show all the subheadings and their bodies.
+
+If non-nil, EVENT should be a mouse event."
+ (interactive (list last-nonmenu-event))
+ (save-excursion
+ (when (mouse-event-p event)
+ (mouse-set-point event))
+ (condition-case nil
+ (pcase (outline--cycle-state)
+ ('hide-all
+ (if (outline-has-subheading-p)
+ (progn (outline-show-children)
+ (message "Only headings"))
+ (outline-show-subtree)
+ (message "Show all")))
+ ('headings-only
(outline-show-subtree)
- (message "Show all")))
- ('headings-only
- (outline-show-subtree)
- (message "Show all"))
- ('show-all
- (outline-hide-subtree)
- (message "Hide all")))
- (outline-before-first-heading nil)))
+ (message "Show all"))
+ ('show-all
+ (outline-hide-subtree)
+ (message "Hide all")))
+ (outline-before-first-heading nil))))
(defvar-local outline--cycle-buffer-state 'show-all
"Internal variable used for tracking buffer cycle state.")
@@ -1624,22 +1638,133 @@ With a prefix argument, show headings up to that LEVEL."
(t
(outline-show-all)
(setq outline--cycle-buffer-state 'show-all)
- (message "Show all")))
- (outline--fix-up-all-buttons)))
+ (message "Show all")))))
-(defvar outline-navigation-repeat-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "C-b") #'outline-backward-same-level)
- (define-key map (kbd "b") #'outline-backward-same-level)
- (define-key map (kbd "C-f") #'outline-forward-same-level)
- (define-key map (kbd "f") #'outline-forward-same-level)
- (define-key map (kbd "C-n") #'outline-next-visible-heading)
- (define-key map (kbd "n") #'outline-next-visible-heading)
- (define-key map (kbd "C-p") #'outline-previous-visible-heading)
- (define-key map (kbd "p") #'outline-previous-visible-heading)
- (define-key map (kbd "C-u") #'outline-up-heading)
- (define-key map (kbd "u") #'outline-up-heading)
- map))
+
+;;; Button/margin indicators
+
+(defun outline--make-button-overlay (type)
+ (let ((o (seq-find (lambda (o)
+ (overlay-get o 'outline-button))
+ (overlays-at (point)))))
+ (unless o
+ (setq o (make-overlay (point) (1+ (point))))
+ (overlay-put o 'evaporate t)
+ (overlay-put o 'follow-link 'mouse-face)
+ (overlay-put o 'mouse-face 'highlight)
+ (overlay-put o 'outline-button t))
+ (let ((icon (icon-elements (if (eq type 'close)
+ (if outline--use-rtl
+ 'outline-close-rtl
+ 'outline-close)
+ 'outline-open)))
+ (inhibit-read-only t))
+ ;; In editing buffers we use overlays only, but in other buffers
+ ;; we use a mix of text properties, text and overlays to make
+ ;; movement commands work more logically.
+ (when (derived-mode-p 'special-mode)
+ (put-text-property (point) (1+ (point)) 'face (plist-get icon 'face)))
+ (if-let ((image (plist-get icon 'image)))
+ (overlay-put o 'display image)
+ (overlay-put o 'display (concat (plist-get icon 'string)
+ (string (char-after (point)))))
+ (overlay-put o 'face (plist-get icon 'face))))
+ o))
+
+(defun outline--make-margin-overlay (type)
+ (let ((o (seq-find (lambda (o)
+ (overlay-get o 'outline-margin))
+ (overlays-at (point)))))
+ (unless o
+ (setq o (make-overlay (point) (1+ (point))))
+ (overlay-put o 'evaporate t)
+ (overlay-put o 'outline-margin t))
+ (let ((icon (icon-elements (if (eq type 'close)
+ (if outline--use-rtl
+ 'outline-close-rtl-in-margins
+ 'outline-close-in-margins)
+ 'outline-open-in-margins))))
+ (overlay-put
+ o 'before-string
+ (propertize " " 'display
+ `((margin ,(if outline--use-rtl
+ 'right-margin 'left-margin))
+ ,(or (plist-get icon 'image)
+ (plist-get icon 'string))))))
+ o))
+
+(defun outline--insert-open-button (&optional use-margins)
+ (with-silent-modifications
+ (save-excursion
+ (beginning-of-line)
+ (if use-margins
+ (outline--make-margin-overlay 'open)
+ (when (derived-mode-p 'special-mode)
+ (let ((inhibit-read-only t))
+ (insert " ")
+ (beginning-of-line)))
+ (let ((o (outline--make-button-overlay 'open)))
+ (overlay-put o 'help-echo "Click to hide")
+ (overlay-put o 'keymap
+ (define-keymap
+ "RET" #'outline-hide-subtree
+ "<mouse-2>" #'outline-hide-subtree)))))))
+
+(defun outline--insert-close-button (&optional use-margins)
+ (with-silent-modifications
+ (save-excursion
+ (beginning-of-line)
+ (if use-margins
+ (outline--make-margin-overlay 'close)
+ (when (derived-mode-p 'special-mode)
+ (let ((inhibit-read-only t))
+ (insert " ")
+ (beginning-of-line)))
+ (let ((o (outline--make-button-overlay 'close)))
+ (overlay-put o 'help-echo "Click to show")
+ (overlay-put o 'keymap
+ (define-keymap
+ "RET" #'outline-show-subtree
+ "<mouse-2>" #'outline-show-subtree)))))))
+
+(defun outline--fix-up-all-buttons (&optional from to)
+ (when (or outline--use-buttons outline--use-margins)
+ (when from
+ (save-excursion
+ (goto-char from)
+ (setq from (line-beginning-position))))
+ (outline-map-region
+ (lambda ()
+ (if (save-excursion
+ (outline-end-of-heading)
+ (seq-some (lambda (o) (eq (overlay-get o 'invisible) 'outline))
+ (overlays-at (point))))
+ (outline--insert-close-button outline--use-margins)
+ (outline--insert-open-button outline--use-margins)))
+ (or from (point-min)) (or to (point-max)))))
+
+(defun outline--fix-buttons-after-change (beg end _len)
+ ;; Handle whole lines
+ (save-excursion (goto-char beg) (setq beg (pos-bol)))
+ (save-excursion (goto-char end) (setq end (pos-eol)))
+ (when outline--use-buttons
+ (remove-overlays beg end 'outline-button t))
+ (when outline--use-margins
+ (remove-overlays beg end 'outline-margin t))
+ (outline--fix-up-all-buttons beg end))
+
+
+(defvar-keymap outline-navigation-repeat-map
+ "C-b" #'outline-backward-same-level
+ "b" #'outline-backward-same-level
+ "C-f" #'outline-forward-same-level
+ "f" #'outline-forward-same-level
+ "C-n" #'outline-next-visible-heading
+ "n" #'outline-next-visible-heading
+ "C-p" #'outline-previous-visible-heading
+ "p" #'outline-previous-visible-heading
+ "C-u" #'outline-up-heading
+ "u" #'outline-up-heading)
(dolist (command '(outline-backward-same-level
outline-forward-same-level
@@ -1648,17 +1773,15 @@ With a prefix argument, show headings up to that LEVEL."
outline-up-heading))
(put command 'repeat-map 'outline-navigation-repeat-map))
-(defvar outline-editing-repeat-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "C-v") #'outline-move-subtree-down)
- (define-key map (kbd "v") #'outline-move-subtree-down)
- (define-key map (kbd "C-^") #'outline-move-subtree-up)
- (define-key map (kbd "^") #'outline-move-subtree-up)
- (define-key map (kbd "C->") #'outline-demote)
- (define-key map (kbd ">") #'outline-demote)
- (define-key map (kbd "C-<") #'outline-promote)
- (define-key map (kbd "<") #'outline-promote)
- map))
+(defvar-keymap outline-editing-repeat-map
+ "C-v" #'outline-move-subtree-down
+ "v" #'outline-move-subtree-down
+ "C-^" #'outline-move-subtree-up
+ "^" #'outline-move-subtree-up
+ "C->" #'outline-demote
+ ">" #'outline-demote
+ "C-<" #'outline-promote
+ "<" #'outline-promote)
(dolist (command '(outline-move-subtree-down
outline-move-subtree-up
@@ -1666,6 +1789,7 @@ With a prefix argument, show headings up to that LEVEL."
outline-promote))
(put command 'repeat-map 'outline-editing-repeat-map))
+
(provide 'outline)
(provide 'noutline)
diff --git a/lisp/pcmpl-git.el b/lisp/pcmpl-git.el
new file mode 100644
index 00000000000..3584fa06732
--- /dev/null
+++ b/lisp/pcmpl-git.el
@@ -0,0 +1,110 @@
+;;; pcmpl-git.el --- Completions for Git -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Package: pcomplete
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides completion rules for the Git program.
+
+;;; Code:
+
+(require 'pcomplete)
+(require 'vc-git)
+
+(defun pcmpl-git--expand-flags (args)
+ "In the list of ARGS, expand arguments of the form --[no-]flag."
+ (mapcan (lambda (arg) (if (string-search "[no-]" arg)
+ (list (string-replace "[no-]" "" arg)
+ (string-replace "[no-]" "no-" arg))
+ (list arg)))
+ args))
+
+(defun pcmpl-git--tracked-file-predicate (&rest args)
+ "Return a predicate function determining the Git status of a file.
+Files listed by `git ls-files ARGS' satisfy the predicate."
+ (when-let ((files (mapcar #'expand-file-name
+ (ignore-errors
+ (apply #'process-lines
+ vc-git-program "ls-files" args)))))
+ (lambda (file)
+ (setq file (expand-file-name file))
+ (if (string-suffix-p "/" file)
+ (seq-some (lambda (f) (string-prefix-p file f))
+ files)
+ (member file files)))))
+
+(defun pcmpl-git--remote-refs (remote)
+ "List the locally known Git revisions from REMOTE."
+ (delq nil
+ (mapcar
+ (let ((re (concat "\\`" (regexp-quote remote) "/\\(.*\\)")))
+ (lambda (s) (when (string-match re s) (match-string 1 s))))
+ (vc-git-revision-table nil))))
+
+;;;###autoload
+(defun pcomplete/git ()
+ "Completion for the `git' command."
+ (let ((subcommands (pcomplete-from-help `(,vc-git-program "help" "-a")
+ :margin "^\\( +\\)[a-z]"
+ :argument "[[:alnum:]-]+")))
+ (while (not (member (pcomplete-arg 1) subcommands))
+ (if (string-prefix-p "-" (pcomplete-arg))
+ (pcomplete-here (pcomplete-from-help `(,vc-git-program "help")
+ :margin "\\(\\[\\)-"
+ :separator " | "
+ :description "\\`"))
+ (pcomplete-here (completion-table-merge
+ subcommands
+ (when (string-prefix-p "-" (pcomplete-arg 1))
+ (pcomplete-entries))))))
+ (let ((subcmd (pcomplete-arg 1)))
+ (while (pcase subcmd
+ ((guard (string-prefix-p "-" (pcomplete-arg)))
+ (pcomplete-here
+ (pcmpl-git--expand-flags
+ (pcomplete-from-help `(,vc-git-program "help" ,subcmd)
+ :argument
+ "-+\\(?:\\[no-\\]\\)?[a-z-]+=?"))))
+ ;; Complete modified tracked files
+ ((or "add" "commit" "restore")
+ (pcomplete-here
+ (pcomplete-entries
+ nil (pcmpl-git--tracked-file-predicate "-m"))))
+ ;; Complete all tracked files
+ ((or "mv" "rm" "grep" "status")
+ (pcomplete-here
+ (pcomplete-entries nil (pcmpl-git--tracked-file-predicate))))
+ ;; Complete revisions
+ ((or "branch" "merge" "rebase" "switch")
+ (pcomplete-here (vc-git-revision-table nil)))
+ ;; Complete revisions and tracked files
+ ;; TODO: diff and log accept revision ranges
+ ((or "checkout" "reset" "show" "diff" "log")
+ (pcomplete-here
+ (completion-table-in-turn
+ (vc-git-revision-table nil)
+ (pcomplete-entries nil (pcmpl-git--tracked-file-predicate)))))
+ ;; Complete remotes and their revisions
+ ((or "fetch" "pull" "push")
+ (pcomplete-here (process-lines vc-git-program "remote"))
+ (pcomplete-here (pcmpl-git--remote-refs (pcomplete-arg 1)))))))))
+
+(provide 'pcmpl-git)
+;;; pcmpl-git.el ends here
diff --git a/lisp/pcmpl-gnu.el b/lisp/pcmpl-gnu.el
index 3c9bf1ec9d2..cdfde5640a7 100644
--- a/lisp/pcmpl-gnu.el
+++ b/lisp/pcmpl-gnu.el
@@ -394,6 +394,40 @@ Return the new list."
(while (pcomplete-here (pcomplete-dirs) nil #'identity))))
;;;###autoload
-(defalias 'pcomplete/gdb 'pcomplete/xargs)
+(defun pcomplete/awk ()
+ "Completion for the `awk' command."
+ (pcomplete-here-using-help "awk --help"
+ :margin "\t"
+ :separator " +"
+ :description "\0"
+ :metavar "[=a-z]+"))
+
+;;;###autoload
+(defun pcomplete/gpg ()
+ "Completion for the `gpg` command."
+ (pcomplete-here-using-help "gpg --help" :narrow-end "^ -se"))
+
+;;;###autoload
+(defun pcomplete/gdb ()
+ "Completion for the `gdb' command."
+ (while
+ (cond
+ ((string= "--args" (pcomplete-arg 1))
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+ ((string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "gdb --help")))
+ (t (pcomplete-here (pcomplete-entries))))))
+
+;;;###autoload
+(defun pcomplete/emacs ()
+ "Completion for the `emacs' command."
+ (pcomplete-here-using-help "emacs --help" :margin "^\\(\\)-"))
+
+;;;###autoload
+(defun pcomplete/emacsclient ()
+ "Completion for the `emacsclient' command."
+ (pcomplete-here-using-help "emacsclient --help" :margin "^\\(\\)-"))
;;; pcmpl-gnu.el ends here
diff --git a/lisp/pcmpl-linux.el b/lisp/pcmpl-linux.el
index 7c072f3d40c..023c655a2a8 100644
--- a/lisp/pcmpl-linux.el
+++ b/lisp/pcmpl-linux.el
@@ -30,6 +30,7 @@
(provide 'pcmpl-linux)
(require 'pcomplete)
+(eval-when-compile (require 'rx))
;; Functions:
@@ -111,4 +112,71 @@ Test is done using `equal'."
(pcomplete-uniquify-list points)
(cons "swap" (pcmpl-linux-mounted-directories))))))
+;;; systemd
+
+(defun pcmpl-linux--systemd-units (&rest args)
+ "Run `systemd list-units ARGS' and return the output as a list."
+ (with-temp-buffer
+ (apply #'call-process
+ "systemctl" nil '(t nil) nil
+ "list-units" "--full" "--legend=no" "--plain" args)
+ (goto-char (point-min))
+ (let (result)
+ (while (re-search-forward (rx bol (group (+ (not space)))
+ (+ space) (+ (not space))
+ (+ space) (group (+ (not space)))
+ (+ space) (+ (not space))
+ (+ space) (group (* nonl)))
+ nil t)
+ (push (match-string 1) result)
+ (put-text-property 0 1 'pcomplete-annotation
+ (concat " " (match-string 2))
+ (car result))
+ (put-text-property 0 1 'pcomplete-description
+ (match-string 3)
+ (car result)))
+ (nreverse result))))
+
+;;;###autoload
+(defun pcomplete/systemctl ()
+ "Completion for the `systemctl' command."
+ (let ((subcmds (pcomplete-from-help
+ "systemctl --help"
+ :margin (rx bol " " (group) alpha)
+ :argument (rx (+ (any alpha ?-)))
+ :metavar (rx (group (+ " " (>= 2 (any upper "[]|."))))))))
+ (while (not (member (pcomplete-arg 1) subcmds))
+ (if (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "systemctl --help"
+ :metavar "[^ ]+"
+ :separator " \\(\\)-"))
+ (pcomplete-here subcmds)))
+ (let ((subcmd (pcomplete-arg 1))
+ (context (if (member "--user" pcomplete-args) "--user" "--system")))
+ (while (pcase subcmd
+ ((guard (string-prefix-p "-" (pcomplete-arg 0)))
+ (pcomplete-here
+ (pcomplete-from-help "systemctl --help")))
+ ;; TODO: suggest only relevant units to each subcommand
+ ("start"
+ (pcomplete-here
+ (pcmpl-linux--systemd-units context "--state" "inactive,failed")))
+ ((or "restart" "stop")
+ (pcomplete-here
+ (pcmpl-linux--systemd-units context "--state" "active")))
+ (_ (pcomplete-here
+ (completion-table-in-turn
+ (pcmpl-linux--systemd-units context "--all")
+ (pcomplete-entries)))))))))
+
+;;;###autoload
+(defun pcomplete/journalctl ()
+ "Completion for the `journalctl' command."
+ (while (if (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "journalctl --help"
+ :metavar "[^ ]+"
+ :separator " \\(\\)-"))
+ (pcomplete-here (mapcar (lambda (s) (concat s "="))
+ (process-lines "journalctl" "--fields"))))))
+
;;; pcmpl-linux.el ends here
diff --git a/lisp/pcmpl-rpm.el b/lisp/pcmpl-rpm.el
index f7925d9d9ec..ebb6b72600c 100644
--- a/lisp/pcmpl-rpm.el
+++ b/lisp/pcmpl-rpm.el
@@ -21,7 +21,8 @@
;;; Commentary:
-;; These functions provide completion rules for the `rpm' command.
+;; These functions provide completion rules for the `rpm' command and
+;; related tools.
;;; Code:
@@ -378,6 +379,46 @@
(t
(error "You must select a mode: -q, -i, -U, --verify, etc"))))))
+;;; DNF
+
+(defvar pcmpl-rpm-dnf-cache-file "/var/cache/dnf/packages.db"
+ "Location of the DNF cache.")
+
+(defun pcmpl-rpm--dnf-packages (status)
+ (when (and (file-exists-p pcmpl-rpm-dnf-cache-file)
+ (executable-find "sqlite3"))
+ (with-temp-message
+ "Getting list of packages..."
+ (process-lines "sqlite3" "-batch" "-init" "/dev/null"
+ pcmpl-rpm-dnf-cache-file
+ (pcase-exhaustive status
+ ('available "select pkg from available")
+ ('installed "select pkg from installed")
+ ('not-installed "\
+select pkg from available where pkg not in (select pkg from installed)"))))))
+
+;;;###autoload
+(defun pcomplete/dnf ()
+ "Completion for the `dnf' command."
+ (let ((subcmds (pcomplete-from-help "dnf help"
+ :margin "^\\(\\)[a-z-]+ "
+ :argument "[a-z-]+")))
+ (while (not (member (pcomplete-arg 1) subcmds))
+ (pcomplete-here (completion-table-merge
+ subcmds
+ (pcomplete-from-help "dnf help"))))
+ (let ((subcmd (pcomplete-arg 1)))
+ (while (pcase subcmd
+ ((guard (pcomplete-match "\\`-" 0))
+ (pcomplete-here
+ (pcomplete-from-help `("dnf" "help" ,subcmd))))
+ ((or "downgrade" "reinstall" "remove")
+ (pcomplete-here (pcmpl-rpm--dnf-packages 'installed)))
+ ((or "install" "mark" "reinstall" "upgrade")
+ (pcomplete-here (pcmpl-rpm--dnf-packages 'not-installed)))
+ ((or "builddep" "changelog" "info" "list" "repoquery" "updateinfo")
+ (pcomplete-here (pcmpl-rpm--dnf-packages 'available))))))))
+
(provide 'pcmpl-rpm)
;;; pcmpl-rpm.el ends here
diff --git a/lisp/pcmpl-unix.el b/lisp/pcmpl-unix.el
index 8774f091c83..0c32f814d0e 100644
--- a/lisp/pcmpl-unix.el
+++ b/lisp/pcmpl-unix.el
@@ -25,7 +25,7 @@
(require 'pcomplete)
-;; User Variables:
+;;; User Variables
(defcustom pcmpl-unix-group-file "/etc/group"
"If non-nil, a string naming the group file on your system."
@@ -56,7 +56,7 @@ being via `pcmpl-ssh-known-hosts-file'."
:group 'pcmpl-unix
:version "24.1")
-;; Functions:
+;;; Shell builtins and core utilities
;;;###autoload
(defun pcomplete/cd ()
@@ -69,34 +69,38 @@ being via `pcmpl-ssh-known-hosts-file'."
;;;###autoload
(defun pcomplete/rmdir ()
"Completion for `rmdir'."
- (while (pcomplete-here (pcomplete-dirs))))
+ (while (if (string-prefix-p "-" (pcomplete-arg))
+ (pcomplete-here (pcomplete-from-help "rmdir --help"))
+ (pcomplete-here (pcomplete-dirs)))))
;;;###autoload
(defun pcomplete/rm ()
- "Completion for `rm'."
- (let ((pcomplete-help "(fileutils)rm invocation"))
- (pcomplete-opt "dfirRv")
- (while (pcomplete-here (pcomplete-all-entries) nil
- #'expand-file-name))))
+ "Completion for the `rm' command."
+ (pcomplete-here-using-help "rm --help"))
;;;###autoload
(defun pcomplete/xargs ()
"Completion for `xargs'."
(while (string-prefix-p "-" (pcomplete-arg 0))
- (pcomplete-here (funcall pcomplete-default-completion-function)))
+ (pcomplete-here (pcomplete-from-help "xargs --help"))
+ (when (pcomplete-match "\\`-[adEIiLnPs]\\'") (pcomplete-here)))
(funcall pcomplete-command-completion-function)
(funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
pcomplete-default-completion-function)))
-;; FIXME: Add completion of sudo-specific arguments.
-(defalias 'pcomplete/sudo #'pcomplete/xargs)
-
;;;###autoload
-(defalias 'pcomplete/time 'pcomplete/xargs)
+(defun pcomplete/time ()
+ "Completion for the `time' command."
+ (pcomplete-opt "p")
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
;;;###autoload
(defun pcomplete/which ()
"Completion for `which'."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "which --help")))
(while (pcomplete-here (funcall pcomplete-command-completion-function))))
(defun pcmpl-unix-read-passwd-file (file)
@@ -129,24 +133,454 @@ documentation), this function returns nil."
(pcmpl-unix-read-passwd-file pcmpl-unix-passwd-file)))
;;;###autoload
+(defun pcomplete/cat ()
+ "Completion for the `cat' command."
+ (pcomplete-here-using-help "cat --help"))
+
+;;;###autoload
+(defun pcomplete/tac ()
+ "Completion for the `tac' command."
+ (pcomplete-here-using-help "tac --help"))
+
+;;;###autoload
+(defun pcomplete/nl ()
+ "Completion for the `nl' command."
+ (pcomplete-here-using-help "nl --help"))
+
+;;;###autoload
+(defun pcomplete/od ()
+ "Completion for the `od' command."
+ (pcomplete-here-using-help "od --help"))
+
+;;;###autoload
+(defun pcomplete/base32 ()
+ "Completion for the `base32' and `base64' commands."
+ (pcomplete-here-using-help "base32 --help"))
+;;;###autoload
+(defalias 'pcomplete/base64 'pcomplete/base32)
+
+;;;###autoload
+(defun pcomplete/basenc ()
+ "Completion for the `basenc' command."
+ (pcomplete-here-using-help "basenc --help"))
+
+;;;###autoload
+(defun pcomplete/fmt ()
+ "Completion for the `fmt' command."
+ (pcomplete-here-using-help "fmt --help"))
+
+;;;###autoload
+(defun pcomplete/pr ()
+ "Completion for the `pr' command."
+ (pcomplete-here-using-help "pr --help"))
+
+;;;###autoload
+(defun pcomplete/fold ()
+ "Completion for the `fold' command."
+ (pcomplete-here-using-help "fold --help"))
+
+;;;###autoload
+(defun pcomplete/head ()
+ "Completion for the `head' command."
+ (pcomplete-here-using-help "head --help"))
+
+;;;###autoload
+(defun pcomplete/tail ()
+ "Completion for the `tail' command."
+ (pcomplete-here-using-help "tail --help"))
+
+;;;###autoload
+(defun pcomplete/split ()
+ "Completion for the `split' command."
+ (pcomplete-here-using-help "split --help"))
+
+;;;###autoload
+(defun pcomplete/csplit ()
+ "Completion for the `csplit' command."
+ (pcomplete-here-using-help "csplit --help"))
+
+;;;###autoload
+(defun pcomplete/wc ()
+ "Completion for the `wc' command."
+ (pcomplete-here-using-help "wc --help"))
+
+;;;###autoload
+(defun pcomplete/sum ()
+ "Completion for the `sum' command."
+ (pcomplete-here-using-help "sum --help"))
+
+;;;###autoload
+(defun pcomplete/cksum ()
+ "Completion for the `cksum' command."
+ (pcomplete-here-using-help "cksum --help"))
+
+;;;###autoload
+(defun pcomplete/b2sum ()
+ "Completion for the `b2sum' command."
+ (pcomplete-here-using-help "b2sum --help"))
+
+;;;###autoload
+(defun pcomplete/md5sum ()
+ "Completion for checksum commands."
+ (pcomplete-here-using-help "md5sum --help"))
+;;;###autoload(defalias 'pcomplete/sha1sum 'pcomplete/md5sum)
+;;;###autoload(defalias 'pcomplete/sha224sum 'pcomplete/md5sum)
+;;;###autoload(defalias 'pcomplete/sha256sum 'pcomplete/md5sum)
+;;;###autoload(defalias 'pcomplete/sha384sum 'pcomplete/md5sum)
+;;;###autoload(defalias 'pcomplete/sha521sum 'pcomplete/md5sum)
+
+;;;###autoload
+(defun pcomplete/sort ()
+ "Completion for the `sort' command."
+ (pcomplete-here-using-help "sort --help"))
+
+;;;###autoload
+(defun pcomplete/shuf ()
+ "Completion for the `shuf' command."
+ (pcomplete-here-using-help "shuf --help"))
+
+;;;###autoload
+(defun pcomplete/uniq ()
+ "Completion for the `uniq' command."
+ (pcomplete-here-using-help "uniq --help"))
+
+;;;###autoload
+(defun pcomplete/comm ()
+ "Completion for the `comm' command."
+ (pcomplete-here-using-help "comm --help"))
+
+;;;###autoload
+(defun pcomplete/ptx ()
+ "Completion for the `ptx' command."
+ (pcomplete-here-using-help "ptx --help"))
+
+;;;###autoload
+(defun pcomplete/tsort ()
+ "Completion for the `tsort' command."
+ (pcomplete-here-using-help "tsort --help"))
+
+;;;###autoload
+(defun pcomplete/cut ()
+ "Completion for the `cut' command."
+ (pcomplete-here-using-help "cut --help"))
+
+;;;###autoload
+(defun pcomplete/paste ()
+ "Completion for the `paste' command."
+ (pcomplete-here-using-help "paste --help"))
+
+;;;###autoload
+(defun pcomplete/join ()
+ "Completion for the `join' command."
+ (pcomplete-here-using-help "join --help"))
+
+;;;###autoload
+(defun pcomplete/tr ()
+ "Completion for the `tr' command."
+ (pcomplete-here-using-help "tr --help"))
+
+;;;###autoload
+(defun pcomplete/expand ()
+ "Completion for the `expand' command."
+ (pcomplete-here-using-help "expand --help"))
+
+;;;###autoload
+(defun pcomplete/unexpand ()
+ "Completion for the `unexpand' command."
+ (pcomplete-here-using-help "unexpand --help"))
+
+;;;###autoload
+(defun pcomplete/ls ()
+ "Completion for the `ls' command."
+ (pcomplete-here-using-help "ls --help"))
+;;;###autoload(defalias 'pcomplete/dir 'pcomplete/ls)
+;;;###autoload(defalias 'pcomplete/vdir 'pcomplete/ls)
+
+;;;###autoload
+(defun pcomplete/cp ()
+ "Completion for the `cp' command."
+ (pcomplete-here-using-help "cp --help"))
+
+;;;###autoload
+(defun pcomplete/dd ()
+ "Completion for the `dd' command."
+ (let ((operands (pcomplete-from-help "dd --help"
+ :argument "[a-z]+="
+ :narrow-start "\n\n"
+ :narrow-end "\n\n")))
+ (while
+ (cond ((pcomplete-match "\\`[io]f=\\(.*\\)" 0)
+ (pcomplete-here (pcomplete-entries)
+ (pcomplete-match-string 1 0)))
+ (t (pcomplete-here operands))))))
+
+;;;###autoload
+(defun pcomplete/install ()
+ "Completion for the `install' command."
+ (pcomplete-here-using-help "install --help"))
+
+;;;###autoload
+(defun pcomplete/mv ()
+ "Completion for the `mv' command."
+ (pcomplete-here-using-help "mv --help"))
+
+;;;###autoload
+(defun pcomplete/shred ()
+ "Completion for the `shred' command."
+ (pcomplete-here-using-help "shred --help"))
+
+;;;###autoload
+(defun pcomplete/ln ()
+ "Completion for the `ln' command."
+ (pcomplete-here-using-help "ln --help"))
+
+;;;###autoload
+(defun pcomplete/mkdir ()
+ "Completion for the `mkdir' command."
+ (pcomplete-here-using-help "mkdir --help"))
+
+;;;###autoload
+(defun pcomplete/mkfifo ()
+ "Completion for the `mkfifo' command."
+ (pcomplete-here-using-help "mkfifo --help"))
+
+;;;###autoload
+(defun pcomplete/mknod ()
+ "Completion for the `mknod' command."
+ (pcomplete-here-using-help "mknod --help"))
+
+;;;###autoload
+(defun pcomplete/readlink ()
+ "Completion for the `readlink' command."
+ (pcomplete-here-using-help "readlink --help"))
+
+;;;###autoload
(defun pcomplete/chown ()
"Completion for the `chown' command."
- (unless (pcomplete-match "\\`-")
- (if (pcomplete-match "\\`[^.]*\\'" 0)
- (pcomplete-here* (pcmpl-unix-user-names))
- (if (pcomplete-match "\\.\\([^.]*\\)\\'" 0)
- (pcomplete-here* (pcmpl-unix-group-names)
- (pcomplete-match-string 1 0))
- (pcomplete-here*))))
+ (while (pcomplete-match "\\`-" 0)
+ (pcomplete-here (pcomplete-from-help "chown --help")))
+ (if (pcomplete-match "\\`[^.]*\\'" 0)
+ (pcomplete-here* (pcmpl-unix-user-names))
+ (if (pcomplete-match "\\.\\([^.]*\\)\\'" 0)
+ (pcomplete-here* (pcmpl-unix-group-names)
+ (pcomplete-match-string 1 0))
+ (pcomplete-here*)))
(while (pcomplete-here (pcomplete-entries))))
;;;###autoload
(defun pcomplete/chgrp ()
"Completion for the `chgrp' command."
- (unless (pcomplete-match "\\`-")
- (pcomplete-here* (pcmpl-unix-group-names)))
+ (while (pcomplete-match "\\`-" 0)
+ (pcomplete-here (pcomplete-from-help "chgrp --help")))
+ (pcomplete-here* (pcmpl-unix-group-names))
(while (pcomplete-here (pcomplete-entries))))
+;;;###autoload
+(defun pcomplete/chmod ()
+ "Completion for the `chmod' command."
+ (pcomplete-here-using-help "chmod --help"))
+
+;;;###autoload
+(defun pcomplete/touch ()
+ "Completion for the `touch' command."
+ (pcomplete-here-using-help "touch --help"))
+
+;;;###autoload
+(defun pcomplete/df ()
+ "Completion for the `df' command."
+ (pcomplete-here-using-help "df --help"))
+
+;;;###autoload
+(defun pcomplete/du ()
+ "Completion for the `du' command."
+ (pcomplete-here-using-help "du --help"))
+
+;;;###autoload
+(defun pcomplete/stat ()
+ "Completion for the `stat' command."
+ (pcomplete-here-using-help "stat --help"))
+
+;;;###autoload
+(defun pcomplete/sync ()
+ "Completion for the `sync' command."
+ (pcomplete-here-using-help "sync --help"))
+
+;;;###autoload
+(defun pcomplete/truncate ()
+ "Completion for the `truncate' command."
+ (pcomplete-here-using-help "truncate --help"))
+
+;;;###autoload
+(defun pcomplete/echo ()
+ "Completion for the `echo' command."
+ (pcomplete-here-using-help '("echo" "--help")))
+
+;;;###autoload
+(defun pcomplete/test ()
+ "Completion for the `test' command."
+ (pcomplete-here-using-help '("[" "--help")
+ :margin "^ +\\([A-Z]+1 \\)?"))
+;;;###autoload(defalias (intern "pcomplete/[") 'pcomplete/test)
+
+;;;###autoload
+(defun pcomplete/tee ()
+ "Completion for the `tee' command."
+ (pcomplete-here-using-help "tee --help"))
+
+;;;###autoload
+(defun pcomplete/basename ()
+ "Completion for the `basename' command."
+ (pcomplete-here-using-help "basename --help"))
+
+;;;###autoload
+(defun pcomplete/dirname ()
+ "Completion for the `dirname' command."
+ (pcomplete-here-using-help "dirname --help"))
+
+;;;###autoload
+(defun pcomplete/pathchk ()
+ "Completion for the `pathchk' command."
+ (pcomplete-here-using-help "pathchk --help"))
+
+;;;###autoload
+(defun pcomplete/mktemp ()
+ "Completion for the `mktemp' command."
+ (pcomplete-here-using-help "mktemp --help"))
+
+;;;###autoload
+(defun pcomplete/realpath ()
+ "Completion for the `realpath' command."
+ (pcomplete-here-using-help "realpath --help"))
+
+;;;###autoload
+(defun pcomplete/id ()
+ "Completion for the `id' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "id --help")))
+ (while (pcomplete-here (pcmpl-unix-user-names))))
+
+;;;###autoload
+(defun pcomplete/groups ()
+ "Completion for the `groups' command."
+ (while (pcomplete-here (pcmpl-unix-user-names))))
+
+;;;###autoload
+(defun pcomplete/who ()
+ "Completion for the `who' command."
+ (pcomplete-here-using-help "who --help"))
+
+;;;###autoload
+(defun pcomplete/date ()
+ "Completion for the `date' command."
+ (pcomplete-here-using-help "date --help"))
+
+;;;###autoload
+(defun pcomplete/nproc ()
+ "Completion for the `nproc' command."
+ (pcomplete-here-using-help "nproc --help"))
+
+;;;###autoload
+(defun pcomplete/uname ()
+ "Completion for the `uname' command."
+ (pcomplete-here-using-help "uname --help"))
+
+;;;###autoload
+(defun pcomplete/hostname ()
+ "Completion for the `hostname' command."
+ (pcomplete-here-using-help "hostname --help"))
+
+;;;###autoload
+(defun pcomplete/uptime ()
+ "Completion for the `uptime' command."
+ (pcomplete-here-using-help "uptime --help"))
+
+;;;###autoload
+(defun pcomplete/chcon ()
+ "Completion for the `chcon' command."
+ (pcomplete-here-using-help "chcon --help"))
+
+;;;###autoload
+(defun pcomplete/runcon ()
+ "Completion for the `runcon' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "runcon --help"))
+ (when (pcomplete-match "\\`-[turl]\\'" 0) (pcomplete-here)))
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+
+;;;###autoload
+(defun pcomplete/chroot ()
+ "Completion for the `chroot' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "chroot --help")))
+ (pcomplete-here (pcomplete-dirs))
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+
+;;;###autoload
+(defun pcomplete/env ()
+ "Completion for the `env' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "env --help"))
+ (when (pcomplete-match "\\`-[uCS]\\'") (pcomplete-here)))
+ (while (pcomplete-match "=" 0) (pcomplete-here)) ; FIXME: Complete env vars
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+
+;;;###autoload
+(defun pcomplete/nice ()
+ "Completion for the `nice' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "nice --help"))
+ (pcomplete-here))
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+
+;;;###autoload
+(defun pcomplete/nohup ()
+ "Completion for the `nohup' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "nohup --help")))
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+
+;;;###autoload
+(defun pcomplete/stdbuf ()
+ "Completion for the `stdbuf' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "stdbuf --help"))
+ (when (pcomplete-match "\\`-[ioe]\\'") (pcomplete-here)))
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+
+;;;###autoload
+(defun pcomplete/timeout ()
+ "Completion for the `timeout' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "timeout --help"))
+ (when (pcomplete-match "\\`-[ks]\\'") (pcomplete-here)))
+ (pcomplete-here) ; eat DURATION argument
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+
+;;;###autoload
+(defun pcomplete/numfmt ()
+ "Completion for the `numfmt' command."
+ (pcomplete-here-using-help "numfmt --help"))
+
+;;;###autoload
+(defun pcomplete/seq ()
+ "Completion for the `seq' command."
+ (pcomplete-here-using-help "seq --help"))
+
+;;; Network commands
;; ssh support by Phil Hagelberg.
;; https://www.emacswiki.org/cgi-bin/wiki/pcmpl-ssh.el
@@ -239,6 +673,18 @@ Includes files as well as host names followed by a colon."
(pcomplete-opt "xl(pcmpl-unix-user-names)")
(pcmpl-unix-complete-hostname))
+;;; Miscellaneous
+
+;;;###autoload
+(defun pcomplete/sudo ()
+ "Completion for the `sudo' command."
+ (while (string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (pcomplete-from-help "sudo --help"))
+ (when (pcomplete-match "\\`-[CDghpRtTUu]\\'") (pcomplete-here)))
+ (funcall pcomplete-command-completion-function)
+ (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+ pcomplete-default-completion-function)))
+
(provide 'pcmpl-unix)
;;; pcmpl-unix.el ends here
diff --git a/lisp/pcmpl-x.el b/lisp/pcmpl-x.el
index 261a3d4e27b..1ede867c5fb 100644
--- a/lisp/pcmpl-x.el
+++ b/lisp/pcmpl-x.el
@@ -28,6 +28,22 @@
(eval-when-compile (require 'cl-lib))
(require 'pcomplete)
+;;; TeX
+
+;;;###autoload
+(defun pcomplete/tex ()
+ "Completion for the `tex' command."
+ (pcomplete-here-using-help "tex --help"
+ :margin "^\\(?:\\[-no\\]\\)?\\(\\)-"))
+;;;###autoload(defalias 'pcomplete/pdftex 'pcomplete/tex)
+;;;###autoload(defalias 'pcomplete/latex 'pcomplete/tex)
+;;;###autoload(defalias 'pcomplete/pdflatex 'pcomplete/tex)
+
+;;;###autoload
+(defun pcomplete/luatex ()
+ "Completion for the `luatex' command."
+ (pcomplete-here-using-help "luatex --help"))
+;;;###autoload(defalias 'pcomplete/lualatex 'pcomplete/luatex)
;;;; tlmgr - https://www.tug.org/texlive/tlmgr.html
@@ -142,6 +158,12 @@
(unless (pcomplete-match "^--" 0)
(pcomplete-here* (pcomplete-dirs-or-entries)))))))
+;;; Grep-like tools
+
+;;;###autoload
+(defun pcomplete/rg ()
+ "Completion for the `rg' command."
+ (pcomplete-here-using-help "rg --help"))
;;;; ack - https://betterthangrep.com
@@ -288,6 +310,8 @@ long options."
(pcmpl-x-ag-options))))
(pcomplete-here* (pcomplete-dirs-or-entries)))))
+;;; Borland
+
;;;###autoload
(defun pcomplete/bcc32 ()
"Completion function for Borland's C++ compiler."
@@ -321,5 +345,24 @@ long options."
;;;###autoload
(defalias 'pcomplete/bcc 'pcomplete/bcc32)
+;;; Network tools
+
+;;;###autoload
+(defun pcomplete/rclone ()
+ "Completion for the `rclone' command."
+ (let ((subcmds (pcomplete-from-help "rclone help"
+ :margin "^ "
+ :argument "[a-z]+"
+ :narrow-start "\n\n")))
+ (while (not (member (pcomplete-arg 1) subcmds))
+ (pcomplete-here (completion-table-merge
+ subcmds
+ (pcomplete-from-help "rclone help flags"))))
+ (let ((subcmd (pcomplete-arg 1)))
+ (while (if (pcomplete-match "\\`-" 0)
+ (pcomplete-here (pcomplete-from-help
+ `("rclone" ,subcmd "--help")))
+ (pcomplete-here (pcomplete-entries)))))))
+
(provide 'pcmpl-x)
;;; pcmpl-x.el ends here
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 0e3d1df7814..8cb0aa3b7ad 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -119,6 +119,9 @@
;;; Code:
(require 'comint)
+(eval-when-compile
+ (require 'cl-lib)
+ (require 'rx))
(defgroup pcomplete nil
"Programmable completion."
@@ -481,6 +484,14 @@ Same as `pcomplete' but using the standard completion UI."
(when completion-ignore-case
(setq table (completion-table-case-fold table)))
(list beg (point) table
+ :annotation-function
+ (lambda (cand)
+ (when (stringp cand)
+ (get-text-property 0 'pcomplete-annotation cand)))
+ :company-docsig
+ (lambda (cand)
+ (when (stringp cand)
+ (get-text-property 0 'pcomplete-help cand)))
:predicate pred
:exit-function
;; If completion is finished, add a terminating space.
@@ -635,15 +646,12 @@ parts of the list.
The OFFSET argument is added to/taken away from the index that will be
used. This is really only useful with `first' and `last', for
accessing absolute argument positions."
- (setq index
- (if (eq index 'first)
- 0
- (if (eq index 'last)
- pcomplete-last
- (- pcomplete-index (or index 0)))))
- (if offset
- (setq index (+ index offset)))
- (nth index pcomplete-args))
+ (nth (+ (pcase index
+ ('first 0)
+ ('last pcomplete-last)
+ (_ (- pcomplete-index (or index 0))))
+ (or offset 0))
+ pcomplete-args))
(defun pcomplete-begin (&optional index offset)
"Return the beginning position of the INDEXth argument.
@@ -1325,6 +1333,133 @@ If specific documentation can't be given, be generic."
(pcomplete-read-hosts pcomplete-hosts-file 'pcomplete--host-name-cache
'pcomplete--host-name-cache-timestamp)))
+;;; Parsing help messages
+
+(defvar pcomplete-from-help (make-hash-table :test #'equal)
+ "Memoization table for function `pcomplete-from-help'.")
+
+(cl-defun pcomplete-from-help (command
+ &rest args
+ &key
+ (margin (rx bol (+ " ")))
+ (argument (rx "-" (+ (any "-" alnum)) (? "=")))
+ (metavar (rx (? " ")
+ (or (+ (any alnum "_-"))
+ (seq "[" (+? nonl) "]")
+ (seq "<" (+? nonl) ">")
+ (seq "{" (+? nonl) "}"))))
+ (separator (rx ", " symbol-start))
+ (description (rx (* nonl)
+ (* "\n" (>= 9 " ") (* nonl))))
+ narrow-start
+ narrow-end)
+ "Parse output of COMMAND into a list of completion candidates.
+
+COMMAND can be a string to be executed in a shell or a list of
+strings (program name and arguments). It should print a help
+message.
+
+A list of arguments is collected after each match of MARGIN.
+Each argument should match ARGUMENT, possibly followed by a match
+of METAVAR. If a match of SEPARATOR follows, then more
+argument-metavar pairs are collected. Finally, a match of
+DESCRIPTION is collected.
+
+Keyword ARGS:
+
+MARGIN: regular expression after which argument descriptions are
+ to be found. Parsing continues at the end of the first match
+ group or, failing that, the entire match.
+
+ARGUMENT: regular expression matching an argument name. The
+ first match group (failing that, the entire match) is collected
+ as the argument name. Parsing continues at the end of the
+ second matching group (failing that, the first group or entire
+ match).
+
+METAVAR: regular expression matching an argument parameter name.
+ The first match group (failing that, the entire match) is
+ collected as the parameter name and used as completion
+ annotation. Parsing continues at the end of the second
+ matching group (failing that, the first group or entire match).
+
+SEPARATOR: regular expression matching the separator between
+ arguments. Parsing continues at the end of the first match
+ group (failing that, the entire match).
+
+DESCRIPTION: regular expression matching the description of an
+ argument. The first match group (failing that, the entire
+ match) is collected as the parameter name and used as
+ completion help. Parsing continues at the end of the first
+ matching group (failing that, the entire match).
+
+NARROW-START, NARROW-END: if non-nil, parsing of the help message
+ is narrowed to the region between the end of the first match
+ group (failing that, the entire match) of these regular
+ expressions."
+ (with-memoization (gethash (cons command args) pcomplete-from-help)
+ (with-temp-buffer
+ (let ((case-fold-search nil)
+ (default-directory (expand-file-name "~/"))
+ (command (if (stringp command)
+ (list shell-file-name
+ shell-command-switch
+ command)
+ command))
+ i result)
+ (apply #'call-process (car command) nil t nil (cdr command))
+ (goto-char (point-min))
+ (narrow-to-region (or (and narrow-start
+ (re-search-forward narrow-start nil t)
+ (or (match-beginning 1) (match-beginning 0)))
+ (point-min))
+ (or (and narrow-end
+ (re-search-forward narrow-end nil t)
+ (or (match-beginning 1) (match-beginning 0)))
+ (point-max)))
+ (goto-char (point-min))
+ (while (re-search-forward margin nil t)
+ (goto-char (or (match-end 1) (match-end 0)))
+ (setq i 0)
+ (while (and (or (zerop i)
+ (and (looking-at separator)
+ (goto-char (or (match-end 1)
+ (match-end 0)))))
+ (looking-at argument))
+ (setq i (1+ i))
+ (goto-char (seq-some #'match-end '(2 1 0)))
+ (push (or (match-string 1) (match-string 0)) result)
+ (when (looking-at metavar)
+ (goto-char (seq-some #'match-end '(2 1 0)))
+ (put-text-property 0 1
+ 'pcomplete-annotation
+ (or (match-string 1) (match-string 0))
+ (car result))))
+ (when (looking-at description)
+ (goto-char (seq-some #'match-end '(2 1 0)))
+ (let ((help (string-clean-whitespace
+ (or (match-string 1) (match-string 0))))
+ (items (take i result)))
+ (while items
+ (put-text-property 0 1 'pcomplete-help help
+ (pop items))))))
+ (nreverse result)))))
+
+(defun pcomplete-here-using-help (command &rest args)
+ "Perform completion for a simple command.
+Offer switches and directory entries as completion candidates.
+The switches are obtained by calling `pcomplete-from-help' with
+COMMAND and ARGS as arguments."
+ (while (cond
+ ((string= "--" (pcomplete-arg 1))
+ (while (pcomplete-here (pcomplete-entries))))
+ ((pcomplete-match "\\`--[^=]+=\\(.*\\)" 0)
+ (pcomplete-here (pcomplete-entries)
+ (pcomplete-match-string 1 0)))
+ ((string-prefix-p "-" (pcomplete-arg 0))
+ (pcomplete-here (apply #'pcomplete-from-help command args)))
+ (t (pcomplete-here (pcomplete-entries))))))
+
(provide 'pcomplete)
;;; pcomplete.el ends here
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
index 167cb4fabe8..10da9cb9abd 100644
--- a/lisp/pixel-scroll.el
+++ b/lisp/pixel-scroll.el
@@ -116,39 +116,37 @@ is always with pixel resolution.")
(defvar mwheel-coalesce-scroll-events)
-(defvar pixel-scroll-precision-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [wheel-down] 'pixel-scroll-precision)
- (define-key map [wheel-up] 'pixel-scroll-precision)
- (define-key map [touch-end] 'pixel-scroll-start-momentum)
- (define-key map [mode-line wheel-down] 'pixel-scroll-precision)
- (define-key map [mode-line wheel-up] 'pixel-scroll-precision)
- (define-key map [mode-line touch-end] 'pixel-scroll-start-momentum)
- (define-key map [header-line wheel-down] 'pixel-scroll-precision)
- (define-key map [header-line wheel-up] 'pixel-scroll-precision)
- (define-key map [header-line touch-end] 'pixel-scroll-start-momentum)
- (define-key map [vertical-scroll-bar wheel-down] 'pixel-scroll-precision)
- (define-key map [vertical-scroll-bar wheel-up] 'pixel-scroll-precision)
- (define-key map [vertical-scroll-bar touch-end] 'pixel-scroll-start-momentum)
- (define-key map [tool-bar wheel-down] 'pixel-scroll-precision)
- (define-key map [tool-bar wheel-up] 'pixel-scroll-precision)
- (define-key map [tool-bar touch-end] 'pixel-scroll-start-momentum)
- (define-key map [left-margin wheel-down] 'pixel-scroll-precision)
- (define-key map [left-margin wheel-up] 'pixel-scroll-precision)
- (define-key map [left-margin touch-end] 'pixel-scroll-start-momentum)
- (define-key map [right-margin wheel-down] 'pixel-scroll-precision)
- (define-key map [right-margin wheel-up] 'pixel-scroll-precision)
- (define-key map [right-margin touch-end] 'pixel-scroll-start-momentum)
- (define-key map [left-fringe wheel-down] 'pixel-scroll-precision)
- (define-key map [left-fringe wheel-up] 'pixel-scroll-precision)
- (define-key map [left-fringe touch-end] 'pixel-scroll-start-momentum)
- (define-key map [right-fringe wheel-down] 'pixel-scroll-precision)
- (define-key map [right-fringe wheel-up] 'pixel-scroll-precision)
- (define-key map [right-fringe touch-end] 'pixel-scroll-start-momentum)
- (define-key map [next] 'pixel-scroll-interpolate-down)
- (define-key map [prior] 'pixel-scroll-interpolate-up)
- map)
- "The key map used by `pixel-scroll-precision-mode'.")
+(defvar-keymap pixel-scroll-precision-mode-map
+ :doc "The key map used by `pixel-scroll-precision-mode'."
+ "<wheel-down>" #'pixel-scroll-precision
+ "<wheel-up>" #'pixel-scroll-precision
+ "<touch-end>" #'pixel-scroll-start-momentum
+ "<mode-line> <wheel-down>" #'pixel-scroll-precision
+ "<mode-line> <wheel-up>" #'pixel-scroll-precision
+ "<mode-line> <touch-end>" #'pixel-scroll-start-momentum
+ "<header-line> <wheel-down>" #'pixel-scroll-precision
+ "<header-line> <wheel-up>" #'pixel-scroll-precision
+ "<header-line> <touch-end>" #'pixel-scroll-start-momentum
+ "<vertical-scroll-bar> <wheel-down>" #'pixel-scroll-precision
+ "<vertical-scroll-bar> <wheel-up>" #'pixel-scroll-precision
+ "<vertical-scroll-bar> <touch-end>" #'pixel-scroll-start-momentum
+ "<tool-bar> <wheel-down>" #'pixel-scroll-precision
+ "<tool-bar> <wheel-up>" #'pixel-scroll-precision
+ "<tool-bar> <touch-end>" #'pixel-scroll-start-momentum
+ "<left-margin> <wheel-down>" #'pixel-scroll-precision
+ "<left-margin> <wheel-up>" #'pixel-scroll-precision
+ "<left-margin> <touch-end>" #'pixel-scroll-start-momentum
+ "<right-margin> <wheel-down>" #'pixel-scroll-precision
+ "<right-margin> <wheel-up>" #'pixel-scroll-precision
+ "<right-margin> <touch-end>" #'pixel-scroll-start-momentum
+ "<left-fringe> <wheel-down>" #'pixel-scroll-precision
+ "<left-fringe> <wheel-up>" #'pixel-scroll-precision
+ "<left-fringe> <touch-end>" #'pixel-scroll-start-momentum
+ "<right-fringe> <wheel-down>" #'pixel-scroll-precision
+ "<right-fringe> <wheel-up>" #'pixel-scroll-precision
+ "<right-fringe> <touch-end>" #'pixel-scroll-start-momentum
+ "<next>" #'pixel-scroll-interpolate-down
+ "<prior>" #'pixel-scroll-interpolate-up)
(defcustom pixel-scroll-precision-use-momentum nil
"If non-nil, continue to scroll the display after wheel movement stops.
@@ -195,7 +193,7 @@ Nil means to not interpolate such scrolls."
:type 'float
:version "29.1")
-(defcustom pixel-scroll-precision-interpolation-factor 4.0
+(defcustom pixel-scroll-precision-interpolation-factor 2.0
"A factor to apply to the distance of an interpolated scroll."
:group 'mouse
:type 'float
@@ -605,19 +603,25 @@ the height of the current window."
(when (< delta 0)
(set-window-vscroll nil (- delta) t t)))))
-(defun pixel-scroll-precision-interpolate (delta &optional old-window)
+(defun pixel-scroll-precision-interpolate (delta &optional old-window factor)
"Interpolate a scroll of DELTA pixels.
OLD-WINDOW is the window which will be selected when redisplay
takes place, or nil for the current window. This results in the
-window being scrolled by DELTA pixels with an animation."
+window being scrolled by DELTA pixels with an animation. FACTOR
+is a scale by which DELTA will be modified. If nil, it defaults
+to `pixel-scroll-precision-interpolation-factor'."
(let ((percentage 0)
(total-time pixel-scroll-precision-interpolation-total-time)
- (factor pixel-scroll-precision-interpolation-factor)
+ (factor (or factor pixel-scroll-precision-interpolation-factor))
(last-time (float-time))
- (time-elapsed 0.0)
+ (time-elapsed 0)
(between-scroll pixel-scroll-precision-interpolation-between-scroll)
(rem (window-parameter nil 'interpolated-scroll-remainder))
- (time (window-parameter nil 'interpolated-scroll-remainder-time)))
+ (time (window-parameter nil 'interpolated-scroll-remainder-time))
+ (last-delta 0))
+ (unless (or (not rem) (eq (< delta 0) (< rem 0)))
+ ;; The direction changed. Clear the remainder.
+ (setq rem nil))
(when (and rem time
(< (- (float-time) time) 1.0)
(eq (< delta 0) (< rem 0)))
@@ -631,18 +635,19 @@ window being scrolled by DELTA pixels with an animation."
(selected-window))
(redisplay t))
(sleep-for between-scroll)
- (setq time-elapsed (+ time-elapsed
- (- (float-time) last-time))
- percentage (/ time-elapsed total-time))
- (let ((throw-on-input nil))
- (if (< delta 0)
- (pixel-scroll-precision-scroll-down
- (ceiling (abs (* (* delta factor)
- (/ between-scroll total-time)))))
- (pixel-scroll-precision-scroll-up
- (ceiling (* (* delta factor)
- (/ between-scroll total-time))))))
- (setq last-time (float-time)))
+ (let ((time (float-time)))
+ (setq time-elapsed (+ time-elapsed
+ (- time last-time))
+ percentage (/ time-elapsed total-time))
+ (let* ((throw-on-input nil)
+ (absolute-delta (* (min 1 percentage) delta factor))
+ (relative-delta (abs
+ (round (- absolute-delta last-delta)))))
+ (setq last-delta absolute-delta)
+ (if (< delta 0)
+ (pixel-scroll-precision-scroll-down relative-delta)
+ (pixel-scroll-precision-scroll-up relative-delta)))
+ (setq last-time time)))
(if (< percentage 1)
(progn
(set-window-parameter nil 'interpolated-scroll-remainder
@@ -821,14 +826,20 @@ It is a vector of the form [ VELOCITY TIME SIGN ]."
"Interpolate a scroll downwards by one page."
(interactive)
(if pixel-scroll-precision-interpolate-page
- (pixel-scroll-precision-interpolate (- (window-text-height nil t)))
+ (pixel-scroll-precision-interpolate (- (window-text-height nil t))
+ ;; Don't use an
+ ;; interpolation factor,
+ ;; since we want exactly 1
+ ;; page to be scrolled.
+ nil 1)
(cua-scroll-up)))
(defun pixel-scroll-interpolate-up ()
"Interpolate a scroll upwards by one page."
(interactive)
(if pixel-scroll-precision-interpolate-page
- (pixel-scroll-precision-interpolate (window-text-height nil t))
+ (pixel-scroll-precision-interpolate (window-text-height nil t)
+ nil 1)
(cua-scroll-down)))
;;;###autoload
diff --git a/lisp/play/hanoi.el b/lisp/play/hanoi.el
index 58fb82b6ed0..1a4b6dbeb11 100644
--- a/lisp/play/hanoi.el
+++ b/lisp/play/hanoi.el
@@ -149,10 +149,9 @@ BITS must be of length nrings. Start at START-TIME."
(setq show-trailing-whitespace nil)
(unwind-protect
(let*
- (;; These lines can cause Emacs to crash if you ask for too
- ;; many rings. If you uncomment them, on most systems you
+ (;; This line can cause Emacs to crash if you ask for too
+ ;; many rings. If you uncomment it, on most systems you
;; can get 10,000+ rings.
- ;;(max-specpdl-size (max max-specpdl-size (* nrings 15)))
;;(max-lisp-eval-depth (max max-lisp-eval-depth (+ nrings 20)))
(vert (not hanoi-horizontal-flag))
(pole-width (length (format "%d" (max 0 (1- nrings)))))
diff --git a/lisp/play/zone.el b/lisp/play/zone.el
index 34523fef057..5ea5bbc9267 100644
--- a/lisp/play/zone.el
+++ b/lisp/play/zone.el
@@ -103,9 +103,24 @@ If the element is a function or a list of a function and a number,
program))))
;;;###autoload
-(defun zone ()
- "Zone out, completely."
- (interactive)
+(defun zone (&optional pgm)
+ "Zone out, completely.
+With a prefix argument the user is prompted for a program to run.
+When called from Lisp the optional argument PGM can be used to
+run a specific program. The program must be a member of
+`zone-programs'."
+ (interactive
+ (and current-prefix-arg
+ (let ((choice (completing-read
+ "Program: "
+ (mapcar
+ (lambda (prog)
+ (substring (symbol-name prog) 9))
+ zone-programs)
+ nil t)))
+ (list (intern (concat "zone-pgm-" choice))))))
+ (unless pgm
+ (setq pgm (aref zone-programs (random (length zone-programs)))))
(save-window-excursion
(let ((f (selected-frame))
(outbuf (get-buffer-create "*zone*"))
@@ -125,8 +140,7 @@ If the element is a function or a list of a function and a number,
(set-window-start (selected-window) (point-min))
(set-window-point (selected-window) wp)
(sit-for 0 500)
- (let ((pgm (elt zone-programs (random (length zone-programs))))
- (ct (and f (frame-parameter f 'cursor-type)))
+ (let ((ct (and f (frame-parameter f 'cursor-type)))
(show-trailing-whitespace nil)
restore)
(when ct
@@ -204,8 +218,7 @@ If the element is a function or a list of a function and a number,
(insert s)))
(defun zone-shift-left ()
- (let ((inhibit-point-motion-hooks t)
- s)
+ (let (s)
(while (not (eobp))
(unless (eolp)
(setq s (buffer-substring (point) (1+ (point))))
@@ -216,8 +229,7 @@ If the element is a function or a list of a function and a number,
(defun zone-shift-right ()
(goto-char (point-max))
- (let ((inhibit-point-motion-hooks t)
- s)
+ (let (s)
(while (not (bobp))
(unless (bolp)
(setq s (buffer-substring (1- (point)) (point)))
@@ -448,8 +460,7 @@ If the element is a function or a list of a function and a number,
(defun zone-fill-out-screen (width height)
(let ((start (window-start))
- (line (make-string width 32))
- (inhibit-point-motion-hooks t))
+ (line (make-string width 32)))
(goto-char start)
;; fill out rectangular ws block
(while (progn (end-of-line)
@@ -664,8 +675,7 @@ If nil, `zone-pgm-random-life' chooses a value from 0-3 (inclusive).")
(setq c (point))
(move-to-column 9)
(setq col (cons (buffer-substring (point) c) col))
-; (let ((inhibit-point-motion-hooks t))
- (end-of-line 0);)
+ (end-of-line 0)
(forward-char -10))
(let ((life-patterns (vector
(if (and col (search-forward "@" max t))
diff --git a/lisp/printing.el b/lisp/printing.el
index d10de24e03c..767648df4d5 100644
--- a/lisp/printing.el
+++ b/lisp/printing.el
@@ -944,7 +944,7 @@
;; `https://www.gnu.org/software/ghostscript/ghostscript.html'
;; gsprint `https://www.cs.wisc.edu/~ghost/gsview/gsprint.htm'.
;; enscript `https://people.ssh.fi/mtr/genscript/'
-;; psnup `http://gnuwin32.sourceforge.net/packages/psutils.htm'
+;; psnup `https://gnuwin32.sourceforge.net/packages/psutils.htm'
;; redmon `http://www.ghostgum.com.au/software/redmon.htm'
;;
;;
@@ -1752,7 +1752,7 @@ Useful links:
`https://linux.die.net/man/1/lp'
* GNU utilities for w32 (cp.exe)
- `http://unxutils.sourceforge.net/'"
+ `https://unxutils.sourceforge.net/'"
:type '(repeat
(list
:tag "PostScript Printer"
@@ -2382,7 +2382,7 @@ Useful links:
`http://gershwin.ens.fr/vdaniel/Doc-Locale/Outils-Gnu-Linux/PsUtils/'
* psnup (PsUtils for Windows)
- `http://gnuwin32.sourceforge.net/packages/psutils.htm'
+ `https://gnuwin32.sourceforge.net/packages/psutils.htm'
* psnup documentation (GNU or Unix - or type `man psnup')
`https://linux.die.net/man/1/psnup'
@@ -5546,13 +5546,11 @@ COMMAND.exe, COMMAND.bat and COMMAND.com in this order."
(defvar pr-i-ps-send 'printer)
-(defvar pr-interface-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map widget-keymap)
- (define-key map "q" 'pr-interface-quit)
- (define-key map "?" 'pr-interface-help)
- map)
- "Keymap for `pr-interface'.")
+(defvar-keymap pr-interface-map
+ :doc "Keymap for `pr-interface'."
+ :parent widget-keymap
+ "q" #'pr-interface-quit
+ "?" #'pr-interface-help)
(defmacro pr-interface-save (&rest body)
`(with-current-buffer pr-i-buffer
diff --git a/lisp/proced.el b/lisp/proced.el
index c278cce9dc7..a774f2dd1e2 100644
--- a/lisp/proced.el
+++ b/lisp/proced.el
@@ -426,7 +426,14 @@ Important: the match ends just after the marker.")
"Name of Proced Log buffer.")
(defconst proced-help-string
- "(n)ext, (p)revious, (m)ark, (u)nmark, (k)ill, (q)uit (type ? for more help)"
+ (concat "\\<proced-mode-map> "
+ "\\[next-line] next, "
+ "\\[previous-line] previous, "
+ "\\[proced-mark] mark, "
+ "\\[proced-unmark] unmark, "
+ "\\[proced-send-signal] kill, "
+ "\\[quit-window] quit "
+ "(type \\[proced-help] for more help)")
"Help string for Proced.")
(defconst proced-header-help-echo
@@ -635,22 +642,27 @@ type \\<proced-mode-map>\\[proced-mark] to mark a process for later commands.
Type \\[proced-send-signal] to send signals to marked processes.
Type \\[proced-renice] to renice marked processes.
-The initial content of a listing is defined by the variable `proced-filter'
-and the variable `proced-format'.
-The variable `proced-filter' specifies which system processes are displayed.
-The variable `proced-format' specifies which attributes are displayed for
-each process. Type \\[proced-filter-interactive] and \\[proced-format-interactive]
-to change the values of `proced-filter' and `proced-format'.
-The current value of the variable `proced-filter' is indicated in the
-mode line.
+The initial content of a listing is defined by the variable
+`proced-filter' and the variable `proced-format'.
+
+The variable `proced-filter' specifies which system processes are
+displayed.
+
+The variable `proced-format' specifies which attributes are
+displayed for each process.
+
+Type \\[proced-filter-interactive] and \\[proced-format-interactive] to \
+change the values of `proced-filter' and
+`proced-format'. The current value of the variable
+`proced-filter' is indicated in the mode line.
The sort order of Proced listings is defined by the variable `proced-sort'.
-Type \\[proced-sort-interactive] or click on a header in the header line
-to change the sort scheme. The current sort scheme is indicated in the
-mode line, using \"+\" or \"-\" for ascending or descending sort order.
+Type \\[proced-sort-interactive] or click on a header in the header \
+line to change the sort scheme.
+The current sort scheme is indicated in the mode line, using
+\"+\" or \"-\" for ascending or descending sort order.
-Type \\[proced-toggle-tree] to toggle whether the listing is
-displayed as process tree.
+Type \\[proced-toggle-tree] to toggle whether the listing is displayed as process tree.
Type \\[proced-toggle-auto-update] to automatically update the
process list. The time interval for updates can be configured
@@ -659,11 +671,11 @@ via `proced-auto-update-interval'.
An existing Proced listing can be refined by typing \\[proced-refine].
Refining an existing listing does not update the variable `proced-filter'.
-The attribute-specific rules for formatting, filtering, sorting, and refining
-are defined in `proced-grammar-alist'.
+The attribute-specific rules for formatting, filtering, sorting,
+and refining are defined in `proced-grammar-alist'.
-After displaying or updating a Proced buffer, Proced runs the normal hook
-`proced-post-display-hook'.
+After displaying or updating a Proced buffer, Proced runs the
+normal hook `proced-post-display-hook'.
\\{proced-mode-map}"
:interactive nil
@@ -1978,7 +1990,7 @@ STRING is an overall summary of the failures."
(proced-why)
(if (eq last-command 'proced-help)
(describe-mode)
- (message proced-help-string)))
+ (message (substitute-command-keys proced-help-string))))
(defun proced-undo ()
"Undo in a Proced buffer.
diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el
index 5002a3bbfae..1aee1107e62 100644
--- a/lisp/progmodes/antlr-mode.el
+++ b/lisp/progmodes/antlr-mode.el
@@ -5,7 +5,7 @@
;; Author: Christoph Wedler <Christoph.Wedler@sap.com>
;; Keywords: languages, ANTLR, code generator
;; Version: 2.2c
-;; URL: http://antlr-mode.sourceforge.net/
+;; URL: https://antlr-mode.sourceforge.net/
;; This file is part of GNU Emacs.
@@ -29,7 +29,7 @@
;; supported options and various other things like running ANTLR from within
;; Emacs.
-;; For details, check <http://antlr-mode.sourceforge.net/> or, if you prefer
+;; For details, check <https://antlr-mode.sourceforge.net/> or, if you prefer
;; the manual style, follow all commands mentioned in the documentation of
;; `antlr-mode'. ANTLR is a LL(k)-based recognition tool which generates
;; lexers, parsers and tree transformers in Java, C++ or Sather and can be
@@ -83,14 +83,6 @@
(require 'easymenu))
(require 'cc-mode)
-;; More compile-time-macros
-(eval-when-compile
- (defmacro save-buffer-state-x (&rest body) ; similar to EMACS/lazy-lock.el
- (declare (debug t) (indent 0))
- `(let ((inhibit-point-motion-hooks t))
- (with-silent-modifications
- ,@body))))
-
(defvar outline-level)
(defvar imenu-use-markers)
(defvar imenu-create-index-function)
@@ -114,12 +106,12 @@
"Major mode for ANTLR grammar files."
:group 'languages
:link '(emacs-commentary-link "antlr-mode.el")
- :link '(url-link "http://antlr-mode.sourceforge.net/")
+ :link '(url-link "https://antlr-mode.sourceforge.net/")
:prefix "antlr-")
(defconst antlr-version "2.2c"
"ANTLR major mode version number.
-Check <http://antlr-mode.sourceforge.net/> for the newest.")
+Check <https://antlr-mode.sourceforge.net/> for the newest.")
;;;===========================================================================
@@ -1320,7 +1312,7 @@ actions if ARG is 0 or negative. See `antlr-action-visibility'.
Display a message unless optional argument SILENT is non-nil."
(interactive "p")
- (save-buffer-state-x
+ (with-silent-modifications
(if (> arg 0)
(let ((regexp (if (= arg 1) "[]}]" "}"))
(diff (and antlr-action-visibility
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index e14f5b9058f..7b45be3c5c1 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -85,11 +85,14 @@ statement-cont.)
Works with: topmost-intro-cont."
(save-excursion
(beginning-of-line)
- (c-backward-syntactic-ws (c-langelem-pos langelem))
- (if (and (memq (char-before) '(?} ?,))
- (not (and c-overloadable-operators-regexp
- (c-after-special-operator-id))))
- c-basic-offset)))
+ (unless (re-search-forward c-fun-name-substitute-key
+ (c-point 'eol) t)
+ (beginning-of-line)
+ (c-backward-syntactic-ws (c-langelem-pos langelem))
+ (if (and (memq (char-before) '(?} ?,))
+ (not (and c-overloadable-operators-regexp
+ (c-after-special-operator-id))))
+ c-basic-offset))))
(defun c-lineup-gnu-DEFUN-intro-cont (langelem)
"Line up the continuation lines of a DEFUN macro in the Emacs C source.
diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el
index 57750a2b394..089fa9ffe4f 100644
--- a/lisp/progmodes/cc-awk.el
+++ b/lisp/progmodes/cc-awk.el
@@ -56,6 +56,7 @@
;; Silence the byte compiler.
(cc-bytecomp-defvar c-new-BEG)
(cc-bytecomp-defvar c-new-END)
+(cc-bytecomp-defvar c-open-string-opener)
(cc-bytecomp-defun c-restore-string-fences)
(cc-bytecomp-defun c-clear-string-fences)
@@ -777,16 +778,20 @@
;; opener, t if it would be a division sign.
;;
;; This function does hidden buffer changes.
- (search-forward-regexp c-awk-string-without-end-here-re nil t) ; a (possibly unterminated) string
- (c-awk-set-string-regexp-syntax-table-properties
- (match-beginning 0) (match-end 0))
- (cond ((looking-at "\"")
- (forward-char)
- t) ; In AWK, ("15" / 5) gives 3 ;-)
- ((looking-at "[\n\r]") ; Unterminated string with EOL.
- (forward-char)
- nil) ; / on next line would start a regexp
- (t nil))) ; Unterminated string at EOB
+ (let ((string-start (if (eq (char-after) ?_) (1+ (point)) (point))))
+ (search-forward-regexp c-awk-string-without-end-here-re nil t) ; a (possibly unterminated) string
+ (c-awk-set-string-regexp-syntax-table-properties
+ (match-beginning 0) (match-end 0))
+ (cond ((looking-at "\"")
+ (forward-char)
+ t) ; In AWK, ("15" / 5) gives 3 ;-)
+ ((looking-at "[\n\r]") ; Unterminated string with EOL.
+ (setq c-open-string-opener string-start)
+ (forward-char)
+ nil) ; / on next line would start a regexp
+ (t ; Unterminated string at EOB
+ (setq c-open-string-opener string-start)
+ nil))))
(defun c-awk-syntax-tablify-/ (anchor anchor-state-/div)
;; Point is at a /. Determine whether this is a division sign or a regexp
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index f867625480c..4f1a08cfa06 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -125,7 +125,7 @@ The result of the body appears to the compiler as a quoted constant.
This variant works around bugs in `eval-when-compile' in various
\(X)Emacs versions. See cc-defs.el for details."
- (declare (indent 0) (debug t))
+ (declare (indent 0) (debug (&rest def-form)))
(if c-inside-eval-when-compile
;; XEmacs 21.4.6 has a bug in `eval-when-compile' in that it
;; evaluates its body at macro expansion time if it's nested
@@ -2629,6 +2629,20 @@ fallback definition for all modes, to break the cycle).")
(defconst c-lang--novalue "novalue")
+(defmacro c-let*-maybe-max-specpdl-size (varlist &rest body)
+ ;; Like let*, but doesn't bind `max-specpdl-size' if that variable
+ ;; is in the bindings list and either doesn't exist or is obsolete.
+ (declare (debug let*) (indent 1))
+ (let ((-varlist- (copy-sequence varlist)) msp-binding)
+ (if (or (not (boundp 'max-specpdl-size))
+ (get 'max-specpdl-size 'byte-obsolete-variable))
+ (cond
+ ((memq 'max-specpdl-size -varlist-)
+ (setq -varlist- (delq 'max-specpdl-size -varlist-)))
+ ((setq msp-binding (assq 'max-specpdl-size -varlist-))
+ (setq -varlist- (delq msp-binding -varlist-)))))
+ `(let* ,-varlist- ,@body)))
+
(defun c-get-lang-constant (name &optional source-files mode)
;; Used by `c-lang-const'.
@@ -2669,21 +2683,22 @@ fallback definition for all modes, to break the cycle).")
;; In that case we just continue with the "assignment" before
;; the one currently being evaluated, thereby creating the
;; illusion if a `setq'-like sequence of assignments.
- (let* ((c-buffer-is-cc-mode mode)
- (source-pos
- (or (assq sym c-lang-constants-under-evaluation)
- (cons sym (vector source nil))))
- ;; Append `c-lang-constants-under-evaluation' even if an
- ;; earlier entry is found. It's only necessary to get
- ;; the recording of dependencies above correct.
- (c-lang-constants-under-evaluation
- (cons source-pos c-lang-constants-under-evaluation))
- (fallback (get mode 'c-fallback-mode))
- value
- ;; Make sure the recursion limits aren't very low
- ;; since the `c-lang-const' dependencies can go deep.
- (max-specpdl-size (max max-specpdl-size 3000))
- (max-lisp-eval-depth (max max-lisp-eval-depth 1000)))
+ (c-let*-maybe-max-specpdl-size
+ ((c-buffer-is-cc-mode mode)
+ (source-pos
+ (or (assq sym c-lang-constants-under-evaluation)
+ (cons sym (vector source nil))))
+ ;; Append `c-lang-constants-under-evaluation' even if an
+ ;; earlier entry is found. It's only necessary to get
+ ;; the recording of dependencies above correct.
+ (c-lang-constants-under-evaluation
+ (cons source-pos c-lang-constants-under-evaluation))
+ (fallback (get mode 'c-fallback-mode))
+ value
+ ;; Make sure the recursion limits aren't very low
+ ;; since the `c-lang-const' dependencies can go deep.
+ (max-specpdl-size (max max-specpdl-size 3000))
+ (max-lisp-eval-depth (max max-lisp-eval-depth 1000)))
(if (if fallback
(let ((backup-source-pos (copy-sequence (cdr source-pos))))
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 94225d6e3e9..223b1e917fe 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -8156,6 +8156,40 @@ multi-line strings (but not C++, for example)."
(c-truncate-lit-pos-cache c-neutralize-pos)))
+(defun c-before-after-change-check-c++-modules (beg end &optional _old_len)
+ ;; Extend the region (c-new-BEG c-new-END) as needed to enclose complete
+ ;; C++20 module statements. This function is called solely from
+ ;; `c-get-state-before-change-functions' and `c-before-font-lock-functions'
+ ;; as part of the before-change and after-change processing for C++.
+ ;;
+ ;; Point is undefined both on entry and exit, and the return value has no
+ ;; significance.
+ (c-save-buffer-state (res bos lit-start)
+ (goto-char end)
+ (if (setq lit-start (c-literal-start))
+ (goto-char lit-start))
+ (when (>= (point) beg)
+ (setq res (c-beginning-of-statement-1 nil t)) ; t is IGNORE-LABELS
+ (setq bos (point))
+ (when (and (memq res '(same previous))
+ (looking-at c-module-key))
+ (setq c-new-BEG (min c-new-BEG (point)))
+ (if (c-syntactic-re-search-forward
+ ";" (min (+ (point) 500) (point-max)) t)
+ (setq c-new-END (max c-new-END (point))))))
+ (when (or (not bos) (< beg bos))
+ (goto-char beg)
+ (when (not (c-literal-start))
+ (setq res (c-beginning-of-statement-1 nil t))
+ (setq bos (point))
+ (when (and (memq res '(same previous))
+ (looking-at c-module-key))
+ (setq c-new-BEG (min c-new-BEG (point)))
+ (if (c-syntactic-re-search-forward
+ ";" (min (+ (point) 500) (point-max)) t)
+ (setq c-new-END (max c-new-END (point)))))))))
+
+
;; Handling of small scale constructs like types and names.
;; Dynamically bound variable that instructs `c-forward-type' to also
@@ -8322,6 +8356,23 @@ multi-line strings (but not C++, for example)."
(goto-char here))))
t)
+(defun c-forward-over-colon-type-list ()
+ ;; If we're at a sequence of characters which can extend from, e.g.,
+ ;; a class name up to a colon introducing an inheritance list,
+ ;; move forward over them, including the colon, and return non-nil.
+ ;; Otherwise return nil, leaving point unmoved.
+ (let ((here (point)) pos)
+ (while (and (re-search-forward c-sub-colon-type-list-re nil t)
+ (not (eq (char-after) ?:))
+ (c-major-mode-is 'c++-mode)
+ (setq pos (c-looking-at-c++-attribute)))
+ (goto-char pos))
+ (if (eq (char-after) ?:)
+ (progn (forward-char)
+ t)
+ (goto-char here)
+ nil)))
+
(defun c-forward-keyword-clause (match)
;; Submatch MATCH in the current match data is assumed to surround a
;; token. If it's a keyword, move over it and any immediately
@@ -8429,12 +8480,11 @@ multi-line strings (but not C++, for example)."
(and c-record-type-identifiers
(progn
;; If a keyword matched both one of the types above and
- ;; this one, we match `c-colon-type-list-re' after the
+ ;; this one, we move forward to the colon following the
;; clause matched above.
(goto-char safe-pos)
- (looking-at c-colon-type-list-re))
+ (c-forward-over-colon-type-list))
(progn
- (goto-char (match-end 0))
(c-forward-syntactic-ws)
(c-forward-keyword-prefixed-id type))
;; There's a type after the `c-colon-type-list-re' match
@@ -8474,25 +8524,40 @@ multi-line strings (but not C++, for example)."
;; recording of any found types that constitute an argument in
;; the arglist.
(c-record-found-types (if c-record-type-identifiers t)))
- (if (catch 'angle-bracket-arglist-escape
- (setq c-record-found-types
- (c-forward-<>-arglist-recur all-types)))
- (progn
- (when (consp c-record-found-types)
- (let ((cur c-record-found-types))
- (while (consp (car-safe cur))
- (c-fontify-new-found-type
- (buffer-substring-no-properties (caar cur) (cdar cur)))
- (setq cur (cdr cur))))
- (setq c-record-type-identifiers
- ;; `nconc' doesn't mind that the tail of
- ;; `c-record-found-types' is t.
- (nconc c-record-found-types c-record-type-identifiers)))
- t)
-
- (setq c-found-types old-found-types)
- (goto-char start)
- nil)))
+ ;; Special handling for C++20's "import <...>" operator.
+ (if (and (c-major-mode-is 'c++-mode)
+ (save-excursion
+ (and (zerop (c-backward-token-2))
+ (looking-at "import\\>\\(?:[^_$]\\|$\\)"))))
+ (when (looking-at "<\\(?:\\\\.\\|[^\\\n\r\t>]\\)*\\(>\\)?")
+ (if (match-beginning 1) ; A terminated <..>
+ (progn
+ (when c-parse-and-markup-<>-arglists
+ (c-mark-<-as-paren (point))
+ (c-mark->-as-paren (match-beginning 1))
+ (c-truncate-lit-pos-cache (point)))
+ (goto-char (match-end 1))
+ t)
+ nil))
+ (if (catch 'angle-bracket-arglist-escape
+ (setq c-record-found-types
+ (c-forward-<>-arglist-recur all-types)))
+ (progn
+ (when (consp c-record-found-types)
+ (let ((cur c-record-found-types))
+ (while (consp (car-safe cur))
+ (c-fontify-new-found-type
+ (buffer-substring-no-properties (caar cur) (cdar cur)))
+ (setq cur (cdr cur))))
+ (setq c-record-type-identifiers
+ ;; `nconc' doesn't mind that the tail of
+ ;; `c-record-found-types' is t.
+ (nconc c-record-found-types c-record-type-identifiers)))
+ t)
+
+ (setq c-found-types old-found-types)
+ (goto-char start)
+ nil))))
(defun c-forward-<>-arglist-recur (all-types)
;; Recursive part of `c-forward-<>-arglist'.
@@ -8872,8 +8937,16 @@ multi-line strings (but not C++, for example)."
;; Got some other operator.
(setq c-last-identifier-range
(cons (point) (match-end 0)))
+ (if (and (eq (char-after) ?\")
+ (eq (char-after (1+ (point))) ?\"))
+ ;; operator"" has an (?)optional tag after it.
+ (progn
+ (goto-char (match-end 0))
+ (c-forward-syntactic-ws lim+)
+ (when (c-on-identifier)
+ (c-forward-token-2 1 nil lim+)))
(goto-char (match-end 0))
- (c-forward-syntactic-ws lim+)
+ (c-forward-syntactic-ws lim+))
(setq pos (point)
res 'operator)))
@@ -9463,17 +9536,151 @@ point unchanged and return nil."
;; Handling of large scale constructs like statements and declarations.
-(defun c-forward-declarator (&optional limit accept-anon)
+(defun c-forward-primary-expression (&optional limit)
+ ;; Go over the primary expression (if any) at point, moving to the next
+ ;; token and return non-nil. If we're not at a primary expression leave
+ ;; point unchanged and return nil.
+ ;;
+ ;; Note that this function is incomplete, handling only those cases expected
+ ;; to be common in a C++20 requires clause.
+ (let ((here (point))
+ (c-restricted-<>-arglists t)
+ (c-parse-and-markup-<>-arglists nil)
+ )
+ (if (cond
+ ((looking-at c-constant-key)
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws limit)
+ t)
+ ((eq (char-after) ?\()
+ (and (c-go-list-forward (point) limit)
+ (eq (char-before) ?\))
+ (progn (c-forward-syntactic-ws limit)
+ t)))
+ ((c-forward-over-compound-identifier)
+ (c-forward-syntactic-ws limit)
+ (while (cond
+ ((looking-at "<")
+ (prog1
+ (c-forward-<>-arglist nil)
+ (c-forward-syntactic-ws limit)))
+ ((looking-at c-opt-identifier-concat-key)
+ (and
+ (zerop (c-forward-token-2 1 nil limit))
+ (prog1
+ (c-forward-over-compound-identifier)
+ (c-forward-syntactic-ws limit))))))
+ t)
+ ((looking-at c-fun-name-substitute-key) ; "requires"
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws limit)
+ (and
+ (or (not (eq (char-after) ?\())
+ (prog1
+ (and (c-go-list-forward (point) limit)
+ (eq (char-before) ?\)))
+ (c-forward-syntactic-ws)))
+ (eq (char-after) ?{)
+ (and (c-go-list-forward (point) limit)
+ (eq (char-before) ?}))
+ (progn
+ (c-forward-syntactic-ws limit)
+ t))))
+ t
+ (goto-char here)
+ nil)))
+
+(defun c-forward-c++-requires-clause (&optional limit)
+ ;; Point is at the keyword "requires". Move forward over the requires
+ ;; clause to the next token after it and return non-nil. If there is no
+ ;; valid requires clause at point, leave point unmoved and return nil.
+ (let ((here (point))
+ final-point)
+ (or limit (setq limit (point-max)))
+ (if (and
+ (zerop (c-forward-token-2 1 nil limit)) ; over "requires".
+ (prog1
+ (c-forward-primary-expression limit)
+ (setq final-point (point))
+ (while
+ (and (looking-at "\\(?:&&\\|||\\)")
+ (progn (goto-char (match-end 0))
+ (c-forward-syntactic-ws limit)
+ (and (< (point) limit)
+ (c-forward-primary-expression limit))))
+ (setq final-point (point)))))
+ (progn (goto-char final-point)
+ t)
+ (goto-char here)
+ nil)))
+
+(defun c-forward-decl-arglist (not-top id-in-parens &optional limit)
+ ;; Point is at an open parenthesis, assumed to be the arglist of a function
+ ;; declaration. Move over this arglist and following syntactic whitespace,
+ ;; and return non-nil. If the construct isn't such an arglist, leave point
+ ;; unmoved and return nil.
+ ;;
+ ;; Note that point is assumed to be at a place where an arglist is expected.
+ ;; Only for C++, where there are other possibilities, is any actual
+ ;; processing done. Otherwise, t is simply returned.
+ (let ((here (point)) got-type)
+ (if (or
+ (not (c-major-mode-is 'c++-mode))
+ (and
+ (or (not not-top)
+ id-in-parens ; Id is in parens, etc.
+ (save-excursion
+ (forward-char)
+ (c-forward-syntactic-ws limit)
+ (looking-at "[*&]")))
+ (save-excursion
+ (let (c-last-identifier-range)
+ (forward-char)
+ (c-forward-syntactic-ws limit)
+ (catch 'is-function
+ (while
+ ;; Go forward one argument at each iteration.
+ (progn
+ (while
+ (cond
+ ((looking-at c-decl-hangon-key)
+ (c-forward-keyword-clause 1))
+ ((looking-at
+ c-noise-macro-with-parens-name-re)
+ (c-forward-noise-clause))))
+ (when (eq (char-after) ?\))
+ (forward-char)
+ (c-forward-syntactic-ws limit)
+ (throw 'is-function t))
+ (setq got-type (c-forward-type))
+ (cond
+ ((null got-type)
+ (throw 'is-function nil))
+ ((not (eq got-type 'maybe))
+ (throw 'is-function t)))
+ (c-forward-declarator limit t t)
+ (eq (char-after) ?,))
+ (forward-char)
+ (c-forward-syntactic-ws))
+ t)))))
+ (and (c-go-list-forward (point) limit)
+ (progn (c-forward-syntactic-ws limit) t))
+ (goto-char here)
+ nil)))
+
+(defun c-forward-declarator (&optional limit accept-anon not-top)
;; Assuming point is at the start of a declarator, move forward over it,
;; leaving point at the next token after it (e.g. a ) or a ; or a ,), or at
;; end of buffer if there is no such token.
;;
- ;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT DECORATED),
- ;; where ID-START and ID-END are the bounds of the declarator's identifier,
- ;; and BRACKETS-AFTER-ID is non-nil if a [...] pair is present after the id.
- ;; GOT-INIT is non-nil when the declarator is followed by "=" or "(",
- ;; DECORATED is non-nil when the identifier is embellished by an operator,
- ;; like "*x", or "(*x)".
+ ;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT DECORATED
+ ;; ARGLIST), where ID-START and ID-END are the bounds of the declarator's
+ ;; identifier, BRACKETS-AFTER-ID is non-nil if a [...] pair is present after
+ ;; the id, and ARGLIST is non-nil either when an arglist has been moved
+ ;; over, or when we have stopped at an unbalanced open-paren. GOT-INIT is
+ ;; non-nil when the declarator is followed by "=" or "(", DECORATED is
+ ;; non-nil when the identifier is embellished by an operator, like "*x", or
+ ;; "(*x)".
;;
;; If ACCEPT-ANON is non-nil, move forward over any "anonymous declarator",
;; i.e. something like the (*) in int (*), such as might be found in a
@@ -9492,7 +9699,8 @@ point unchanged and return nil."
;; array/struct initialization) or "=" or terminating delimiter
;; (e.g. "," or ";" or "}").
(let ((here (point))
- id-start id-end brackets-after-id paren-depth decorated)
+ id-start id-end brackets-after-id paren-depth decorated
+ got-init arglist double-double-quote)
(or limit (setq limit (point-max)))
(if (and
(< (point) limit)
@@ -9513,25 +9721,42 @@ point unchanged and return nil."
((and c-opt-cpp-prefix
(looking-at c-noise-macro-with-parens-name-re))
(c-forward-noise-clause))
+ ;; Special handling for operator<op>.
+ ((and c-opt-op-identifier-prefix
+ (looking-at c-opt-op-identifier-prefix))
+ (goto-char (match-end 1))
+ (c-forward-syntactic-ws limit)
+ (setq id-start (point))
+ (if (looking-at c-overloadable-operators-regexp)
+ (progn
+ (when (and (c-major-mode-is 'c++-mode)
+ (eq (char-after) ?\")
+ (eq (char-after (1+ (point))) ?\"))
+ (setq double-double-quote t))
+ (goto-char (match-end 0))
+ (c-forward-syntactic-ws limit)
+ (setq got-identifier t)
+ nil)
+ t))
((and (looking-at c-type-decl-prefix-key)
(if (and (c-major-mode-is 'c++-mode)
(match-beginning 4)) ; Was 3 - 2021-01-01
- ;; If the third submatch matches in C++ then
+ ;; If the fourth submatch matches in C++ then
;; we're looking at an identifier that's a
;; prefix only if it specifies a member pointer.
(progn
(setq id-start (point))
- (c-forward-name)
- (if (save-match-data
- (looking-at "\\(::\\)"))
- ;; We only check for a trailing "::" and
- ;; let the "*" that should follow be
- ;; matched in the next round.
- t
- ;; It turned out to be the real identifier,
- ;; so flag that and stop.
- (setq got-identifier t)
- nil))
+ (when (c-forward-name)
+ (if (save-match-data
+ (looking-at "\\(::\\)"))
+ ;; We only check for a trailing "::" and
+ ;; let the "*" that should follow be
+ ;; matched in the next round.
+ t
+ ;; It turned out to be the real identifier,
+ ;; so flag that and stop.
+ (setq got-identifier t)
+ nil)))
t))
(if (save-match-data
(looking-at c-type-decl-operator-prefix-key))
@@ -9557,25 +9782,49 @@ point unchanged and return nil."
(accept-anon
(setq id-start nil id-end nil)
t)
- (t (/= (point) here))))
+ (t nil)))
+
+ (progn
+ (c-forward-syntactic-ws limit)
+ (when (and double-double-quote ; C++'s operator"" _tag
+ (c-on-identifier))
+ (c-forward-token-2 1 nil limit))
+ t)
;; Skip out of the parens surrounding the identifier. If closing
;; parens are missing, this form returns nil.
(or (= paren-depth 0)
- (c-safe (goto-char (scan-lists (point) 1 paren-depth))))
+ (prog1
+ (c-safe (goto-char (scan-lists (point) 1 paren-depth)))
+ (c-forward-syntactic-ws)))
(or (eq (point) (point-max)) ; No token after identifier.
(< (point) limit))
;; Skip over any trailing bit, such as "__attribute__".
(progn
- (while (cond
- ((looking-at c-decl-hangon-key)
- (c-forward-keyword-clause 1))
- ((and c-opt-cpp-prefix
- (looking-at c-noise-macro-with-parens-name-re))
- (c-forward-noise-clause))))
- (<= (point) limit))
+ (while (cond
+ ((looking-at c-decl-hangon-key)
+ (c-forward-keyword-clause 1))
+ ((looking-at c-type-decl-suffix-key)
+ (cond
+ ((save-match-data
+ (looking-at c-fun-name-substitute-key))
+ (c-forward-c++-requires-clause))
+ ((eq (char-after) ?\()
+ (if (c-forward-decl-arglist not-top decorated limit)
+ (progn (setq arglist t
+ got-init nil)
+ t)
+ (if (c-go-list-forward (point) limit)
+ t
+ (setq arglist t) ; For unbalanced (.
+ nil)))
+ (t (c-forward-keyword-clause 1))))
+ ((and c-opt-cpp-prefix
+ (looking-at c-noise-macro-with-parens-name-re))
+ (c-forward-noise-clause))))
+ (<= (point) limit))
;; Search syntactically to the end of the declarator (";",
;; ",", a closing paren, eob etc) or to the beginning of an
@@ -9583,45 +9832,56 @@ point unchanged and return nil."
;; Note that square brackets are now not also treated as
;; initializers, since this broke when there were also
;; initializing brace lists.
- (let (found)
- (while
- (and (< (point) limit)
- (progn
- ;; In the next loop, we keep searching forward whilst
- ;; we find ":"s which aren't single colons inside C++
- ;; "for" statements.
- (while
- (and
- (< (point) limit)
- (setq found
- (c-syntactic-re-search-forward
- "[;:,]\\|\\s)\\|\\(=\\|\\s(\\)"
- limit t t))
- (eq (char-before) ?:)
- (if (looking-at c-:-op-cont-regexp)
- (progn (goto-char (match-end 0)) t)
- (not
- (and (c-major-mode-is '(c++-mode java-mode))
- (save-excursion
- (and
- (c-go-up-list-backward)
- (eq (char-after) ?\()
- (progn (c-backward-syntactic-ws)
- (c-simple-skip-symbol-backward))
- (looking-at c-paren-stmt-key))))))))
- found)
- (eq (char-before) ?\[)
- (c-go-up-list-forward))
- (setq brackets-after-id t))
- (when found (backward-char))
- (<= (point) limit)))
- (list id-start id-end brackets-after-id (match-beginning 1) decorated)
+ (or (eq (char-after) ?\() ; Not an arglist.
+ (let (found)
+ (while
+ (and (< (point) limit)
+ (progn
+ ;; In the next loop, we keep searching forward
+ ;; whilst we find ":"s which aren't single colons
+ ;; inside C++ "for" statements.
+ (while
+ (and
+ (< (point) limit)
+ (prog1
+ (setq found
+ (c-syntactic-re-search-forward
+ "[;:,]\\|\\(=\\|\\s(\\)"
+ limit 'limit t))
+ (setq got-init
+ (and found (match-beginning 1))))
+ (eq (char-before) ?:)
+ (not
+ (and (c-major-mode-is '(c++-mode java-mode))
+ (save-excursion
+ (and
+ (c-go-up-list-backward)
+ (eq (char-after) ?\()
+ (progn (c-backward-syntactic-ws)
+ (c-simple-skip-symbol-backward))
+ (looking-at c-paren-stmt-key)))))
+ (if (looking-at c-:-op-cont-regexp)
+ (progn (goto-char (match-end 0)) t)
+ ;; Does this : introduce the class
+ ;; initialization list, or a bitfield?
+ (not arglist)))) ; Carry on for a bitfield
+ found)
+ (when (eq (char-before) ?\[)
+ (setq brackets-after-id t)
+ (prog1 (c-go-up-list-forward)
+ (c-forward-syntactic-ws)))))
+ (when (and found
+ (memq (char-before) '(?\; ?\: ?, ?= ?\( ?\[ ?{)))
+ (backward-char))
+ (<= (point) limit))))
+ (list id-start id-end brackets-after-id got-init decorated arglist)
(goto-char here)
nil)))
(defun c-do-declarators
- (cdd-limit cdd-list cdd-not-top cdd-comma-prop cdd-function)
+ (cdd-limit cdd-list cdd-not-top cdd-comma-prop cdd-function
+ &optional cdd-accept-anon)
"Assuming point is at the start of a comma separated list of declarators,
apply CDD-FUNCTION to each declarator (when CDD-LIST is non-nil) or just the
first declarator (when CDD-LIST is nil). When CDD-FUNCTION is nil, no
@@ -9646,6 +9906,9 @@ Stop at or before CDD-LIMIT (which may NOT be nil).
If CDD-NOT-TOP is non-nil, we are not at the top-level (\"top-level\" includes
being directly inside a class or namespace, etc.).
+If CDD-ACCEPT-ANON is non-nil, we also process declarators without names,
+e.g. \"int (*)(int)\" in a function prototype.
+
Return non-nil if we've reached the token after the last declarator (often a
semicolon, or a comma when CDD-LIST is nil); otherwise (when we hit CDD-LIMIT,
or fail otherwise) return nil, leaving point at the beginning of the putative
@@ -9657,67 +9920,25 @@ This function might do hidden buffer changes."
;; CDD-FUNCTION.
(let
((cdd-pos (point)) cdd-next-pos cdd-id-start cdd-id-end
- cdd-decl-res cdd-got-func cdd-got-type cdd-got-init
+ cdd-decl-res cdd-got-func cdd-got-init
c-last-identifier-range cdd-exhausted cdd-after-block)
;; The following `while' applies `cdd-function' to a single declarator id
;; each time round. It loops only when CDD-LIST is non-nil.
(while
(and (not cdd-exhausted)
- (setq cdd-decl-res (c-forward-declarator cdd-limit)))
+ (setq cdd-decl-res (c-forward-declarator
+ cdd-limit cdd-accept-anon cdd-not-top)))
+
(setq cdd-next-pos (point)
cdd-id-start (car cdd-decl-res)
cdd-id-end (cadr cdd-decl-res)
- cdd-got-func (and (eq (char-after) ?\()
- (or (not (c-major-mode-is 'c++-mode))
- (not cdd-not-top)
- (car (cddr (cddr cdd-decl-res))) ; Id is in
- ; parens, etc.
- (save-excursion
- (forward-char)
- (c-forward-syntactic-ws)
- (looking-at "[*&]")))
- (not (car (cddr cdd-decl-res)))
- (or (not (c-major-mode-is 'c++-mode))
- (save-excursion
- (let (c-last-identifier-range)
- (forward-char)
- (c-forward-syntactic-ws)
- (catch 'is-function
- (while
- (progn
- (while
- (cond
- ((looking-at c-decl-hangon-key)
- (c-forward-keyword-clause 1))
- ((looking-at c-noise-macro-with-parens-name-re)
- (c-forward-noise-clause))))
- (if (eq (char-after) ?\))
- (throw 'is-function t))
- (setq cdd-got-type (c-forward-type))
- (cond
- ((null cdd-got-type)
- (throw 'is-function nil))
- ((not (eq cdd-got-type 'maybe))
- (throw 'is-function t)))
- (c-forward-declarator nil t)
- (eq (char-after) ?,))
- (forward-char)
- (c-forward-syntactic-ws))
- t)))))
- cdd-got-init (and (cadr (cddr cdd-decl-res))
- (char-after)))
+ cdd-got-func (cadr (cddr (cddr cdd-decl-res)))
+ cdd-got-init (and (cadr (cddr cdd-decl-res)) (char-after)))
;; Jump past any initializer or function prototype to see if
;; there's a ',' to continue at.
- (cond (cdd-got-func
- ;; Skip a parenthesized initializer (C++) or a function
- ;; prototype.
- (if (c-go-list-forward (point) cdd-limit) ; over the parameter list.
- (c-forward-syntactic-ws cdd-limit)
- (setq cdd-exhausted t))) ; unbalanced parens
-
- (cdd-got-init ; "=" sign OR opening "(", "[", or "("
+ (cond (cdd-got-init ; "=" sign OR opening "(", "[", or "("
;; Skip an initializer expression in braces, whether or not (in
;; C++ Mode) preceded by an "=". Be careful that the brace list
;; isn't a code block or a struct (etc.) block.
@@ -9740,8 +9961,9 @@ This function might do hidden buffer changes."
(t (c-forward-syntactic-ws cdd-limit)))
(if cdd-function
- (funcall cdd-function cdd-id-start cdd-id-end cdd-next-pos
- cdd-not-top cdd-got-func cdd-got-init))
+ (save-excursion
+ (funcall cdd-function cdd-id-start cdd-id-end cdd-next-pos
+ cdd-not-top cdd-got-func cdd-got-init)))
;; If a ',' is found we set cdd-pos to the next declarator and iterate.
(if (and cdd-list (< (point) cdd-limit) (looking-at ","))
@@ -9841,13 +10063,13 @@ This function might do hidden buffer changes."
;;
;;
;;
- ;; The second element of the return value is non-nil when a
- ;; `c-typedef-decl-kwds' specifier is found in the declaration.
- ;; Specifically it is a dotted pair (A . B) where B is t when a
- ;; `c-typedef-kwds' ("typedef") is present, and A is t when some
- ;; other `c-typedef-decl-kwds' (e.g. class, struct, enum)
- ;; specifier is present. I.e., (some of) the declared
- ;; identifier(s) are types.
+ ;; The second element of the return value is non-nil when something
+ ;; indicating the identifier is a type occurs in the declaration.
+ ;; Specifically it is nil, or a three element list (A B C) where C is t
+ ;; when context is '<> and the "identifier" is a found type, B is t when a
+ ;; `c-typedef-kwds' ("typedef") is present, and A is t when some other
+ ;; `c-typedef-declkwds' (e.g. class, struct, enum) specifier is present.
+ ;; I.e., (some of) the declared identifier(s) are types.
;;
;; The third element of the return value is non-nil when the declaration
;; parsed might be an expression. The fourth element is the position of
@@ -9923,6 +10145,9 @@ This function might do hidden buffer changes."
at-type-decl
;; Set if we've a "typedef" keyword.
at-typedef
+ ;; Set if `context' is '<> and the identifier is definitely a type, or
+ ;; has already been recorded as a found type.
+ at-<>-type
;; Set if we've found a specifier that can start a declaration
;; where there's no type.
maybe-typeless
@@ -10001,6 +10226,11 @@ This function might do hidden buffer changes."
(setq kwd-sym (c-keyword-sym (match-string 1)))
(save-excursion
(c-forward-keyword-clause 1)
+ (when (and (c-major-mode-is 'c++-mode)
+ (c-keyword-member kwd-sym 'c-<>-sexp-kwds)
+ (save-match-data
+ (looking-at c-fun-name-substitute-key)))
+ (c-forward-c++-requires-clause))
(setq kwd-clause-end (point))))
((and c-opt-cpp-prefix
(looking-at c-noise-macro-with-parens-name-re))
@@ -10040,6 +10270,11 @@ This function might do hidden buffer changes."
(point))))
found-type-list))
+ ;; Might we have a C++20 concept? i.e. template<foo bar>?
+ (setq at-<>-type
+ (and (eq context '<>)
+ (memq found-type '(t known prefix found))))
+
;; Signal a type declaration for "struct foo {".
(when (and backup-at-type-decl
(eq (char-after) ?{))
@@ -10328,8 +10563,11 @@ This function might do hidden buffer changes."
t)
(when (if (save-match-data (looking-at "\\s("))
(c-safe (c-forward-sexp 1) t)
- (goto-char (match-end 1))
- t)
+ (if (save-match-data
+ (looking-at c-fun-name-substitute-key)) ; requires
+ (c-forward-c++-requires-clause)
+ (goto-char (match-end 1))
+ t))
(when (and (not got-suffix-after-parens)
(= paren-depth 0))
(setq got-suffix-after-parens (match-beginning 0)))
@@ -10922,8 +11160,8 @@ This function might do hidden buffer changes."
(c-forward-type))))
(list id-start
- (and (or at-type-decl at-typedef)
- (cons at-type-decl at-typedef))
+ (and (or at-type-decl at-typedef at-<>-type)
+ (list at-type-decl at-typedef at-<>-type))
maybe-expression
type-start
(or (eq context 'top) make-top)))
@@ -12380,6 +12618,8 @@ comment at the start of cc-engine.el for more info."
in-paren 'in-paren))
((looking-at c-pre-brace-non-bracelist-key)
(setq braceassignp nil))
+ ((looking-at c-fun-name-substitute-key)
+ (setq braceassignp nil))
((looking-at c-return-key))
((and (looking-at c-symbol-start)
(not (looking-at c-keywords-regexp)))
@@ -12390,6 +12630,11 @@ comment at the start of cc-engine.el for more info."
(setq after-type-id-pos (point))))
((eq (char-after) ?\()
(setq parens-before-brace t)
+ ;; Have we a requires with a parenthesis list?
+ (when (save-excursion
+ (and (zerop (c-backward-token-2 1 nil lim))
+ (looking-at c-fun-name-substitute-key)))
+ (setq braceassignp nil))
nil)
(t nil))
(save-excursion
@@ -14152,6 +14397,25 @@ comment at the start of cc-engine.el for more info."
(goto-char placeholder)
(c-add-syntax 'inher-cont (c-point 'boi)))
+ ;; CASE 5D.7: Continuation of a "concept foo =" line in C++20 (or
+ ;; similar).
+ ((and c-equals-nontype-decl-key
+ (save-excursion
+ (prog1
+ (and (zerop (c-backward-token-2 1 nil lim))
+ (looking-at c-operator-re)
+ (equal (match-string 0) "=")
+ (zerop (c-backward-token-2 1 nil lim))
+ (looking-at c-symbol-start)
+ (not (looking-at c-keywords-regexp))
+ (zerop (c-backward-token-2 1 nil lim))
+ (looking-at c-equals-nontype-decl-key)
+ (eq (c-beginning-of-statement-1 lim) 'same))
+ (setq placeholder (point)))))
+ (goto-char placeholder)
+ (c-add-stmt-syntax 'topmost-intro-cont nil nil containing-sexp
+ paren-state))
+
;; CASE 5D.5: Continuation of the "expression part" of a
;; top level construct. Or, perhaps, an unrecognized construct.
(t
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index f34f7f177db..b4ff32b9070 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -99,6 +99,8 @@
(cc-bytecomp-defun c-font-lock-invalid-string)
(cc-bytecomp-defun c-font-lock-fontify-region)
+(cc-bytecomp-defvar font-lock-reference-face) ; For Emacs 29
+
;; Note that font-lock in XEmacs doesn't expand face names as
;; variables, so we have to use the (eval . FORM) in the font lock
@@ -112,8 +114,10 @@
;; In Emacs font-lock-builtin-face has traditionally been
;; used for preprocessor directives.
'font-lock-builtin-face)
- (t
- 'font-lock-reference-face)))
+ ((and (c-face-name-p 'font-lock-reference-face)
+ (eq font-lock-reference-face 'font-lock-reference-face))
+ 'font-lock-reference-face)
+ (t 'font-lock-constant-face)))
(cc-bytecomp-defvar font-lock-constant-face)
@@ -163,9 +167,8 @@
(defconst c-doc-markup-face-name
(if (c-face-name-p 'font-lock-doc-markup-face)
- ;; If it happens to occur in the future. (Well, the more
- ;; pragmatic reason is to get unique faces for the test
- ;; suite.)
+ ;; Exists in Emacs 28+. (For other emacsen, the pragmatic
+ ;; reason is to get unique faces for the test suite.)
'font-lock-doc-markup-face
c-label-face-name))
@@ -558,8 +561,10 @@ stuff. Used on level 1 and higher."
(c-lang-const c-opt-cpp-prefix)
re
(c-lang-const c-syntactic-ws)
- "\\(<[^>\n\r]*>?\\)")
- `(,(+ ncle-depth re-depth sws-depth 1)
+ "\\(<\\([^>\n\r]*\\)>?\\)")
+ `(,(+ ncle-depth re-depth sws-depth
+ (if (featurep 'xemacs) 2 1)
+ )
font-lock-string-face t)
`((let ((beg (match-beginning
,(+ ncle-depth re-depth sws-depth 1)))
@@ -878,6 +883,27 @@ casts and declarations are fontified. Used on level 2 and higher."
c-reference-face-name))
(goto-char (match-end 1))))))))))
+ ;; Module declarations (e.g. in C++20).
+ ,@(when (c-major-mode-is 'c++-mode)
+ '(c-font-lock-c++-modules))
+
+ ;; The next regexp is highlighted with narrowing. This is so that the
+ ;; final "context" bit of the regexp, "\\(?:[^=]\\|$\\)", which cannot
+ ;; match anything non-empty at LIMIT, will match "$" instead.
+ ,@(when (c-lang-const c-equals-nontype-decl-kwds)
+ `((,(byte-compile
+ `(lambda (limit)
+ (save-restriction
+ (narrow-to-region (point-min) limit)
+ ,(c-make-font-lock-search-form
+ (concat (c-lang-const c-equals-nontype-decl-key) ;no \\(
+ (c-lang-const c-simple-ws) "+\\("
+ (c-lang-const c-symbol-key) "\\)"
+ (c-lang-const c-simple-ws) "*"
+ "=\\(?:[^=]\\|$\\)")
+ `((,(+ 1 (c-lang-const c-simple-ws-depth))
+ font-lock-type-face t)))))))))
+
;; Fontify the special declarations in Objective-C.
,@(when (c-major-mode-is 'objc-mode)
`(;; Fontify class names in the beginning of message expressions.
@@ -1066,7 +1092,7 @@ casts and declarations are fontified. Used on level 2 and higher."
nil)
(defun c-font-lock-declarators (limit list types not-top
- &optional template-class)
+ &optional template-class accept-anon)
;; Assuming the point is at the start of a declarator in a declaration,
;; fontify the identifier it declares. (If TYPES is t, it does this via the
;; macro `c-fontify-types-and-refs'.)
@@ -1086,6 +1112,8 @@ casts and declarations are fontified. Used on level 2 and higher."
;; a default (introduced by "="), it will be fontified as a type.
;; E.g. "<class X = Y>".
;;
+ ;; ACCEPT-ANON is non-nil when we accept anonymous declarators.
+ ;;
;; Nil is always returned. The function leaves point at the delimiter after
;; the last declarator it processes.
;;
@@ -1098,37 +1126,51 @@ casts and declarations are fontified. Used on level 2 and higher."
limit list not-top
(cond ((eq types t) 'c-decl-type-start)
((null types) 'c-decl-id-start))
- (lambda (id-start _id-end end-pos _not-top is-function init-char)
+ (lambda (id-start id-end end-pos _not-top is-function init-char)
(if (eq types t)
- ;; Register and fontify the identifier as a type.
- (let ((c-promote-possible-types t))
- (goto-char id-start)
- (c-forward-type))
- ;; The following doesn't work properly (yet, 2018-09-22).
- ;; (c-put-font-lock-face id-start id-end
- ;; (if is-function
- ;; 'font-lock-function-name-face
- ;; 'font-lock-variable-name-face))
- (when (and c-last-identifier-range
- (not (get-text-property (car c-last-identifier-range)
- 'face)))
- ;; We use `c-last-identifier-range' rather than `id-start' and
- ;; `id-end', since the latter two can be erroneous. E.g. in
- ;; "~Foo", `id-start' is at the tilde. This is a bug in
- ;; `c-forward-declarator'.
- (c-put-font-lock-face (car c-last-identifier-range)
- (cdr c-last-identifier-range)
- (cond
- ((not (memq types '(nil t))) types)
- (is-function 'font-lock-function-name-face)
- (t 'font-lock-variable-name-face)))))
+ (when id-start
+ ;; Register and fontify the identifier as a type.
+ (let ((c-promote-possible-types t))
+ (goto-char id-start)
+ (c-forward-type)))
+ (when id-start
+ (goto-char id-start)
+ (when c-opt-identifier-prefix-key
+ (unless (and (looking-at c-opt-identifier-prefix-key) ; For operator~
+ (eq (match-end 1) id-end))
+ (while (and (< (point) id-end)
+ (re-search-forward c-opt-identifier-prefix-key id-end t))
+ (c-forward-syntactic-ws limit))))
+ ;; Only apply the face when the text doesn't have one yet.
+ ;; Exception: The "" in C++'s operator"" will already wrongly have
+ ;; string face.
+ (when (memq (get-text-property (point) 'face)
+ '(nil font-lock-string-face))
+ (c-put-font-lock-face (point) id-end
+ (cond
+ ((not (memq types '(nil t))) types)
+ (is-function 'font-lock-function-name-face)
+ (t 'font-lock-variable-name-face))))
+ ;; Fontify any _tag in C++'s operator"" _tag.
+ (when (and
+ (c-major-mode-is 'c++-mode)
+ (equal (buffer-substring-no-properties id-start id-end)
+ "\"\""))
+ (goto-char id-end)
+ (c-forward-syntactic-ws limit)
+ (when (c-on-identifier)
+ (c-put-font-lock-face
+ (point)
+ (progn (c-forward-over-token) (point))
+ font-lock-function-name-face)))))
(and template-class
(eq init-char ?=) ; C++ "<class X = Y>"?
(progn
(goto-char end-pos)
(c-forward-token-2 1 nil limit) ; Over "="
(let ((c-promote-possible-types t))
- (c-forward-type t))))))
+ (c-forward-type t)))))
+ accept-anon) ; Last argument to c-do-declarators.
nil))
(defun c-get-fontification-context (match-pos not-front-decl &optional toplev)
@@ -1269,15 +1311,19 @@ casts and declarations are fontified. Used on level 2 and higher."
(or (memq type '(c-decl-arg-start c-decl-type-start))
(and
(progn (c-backward-syntactic-ws) t)
- (c-back-over-compound-identifier)
- (progn
- (c-backward-syntactic-ws)
- (or (bobp)
- (progn
- (setq type (c-get-char-property (1- (point))
- 'c-type))
- (memq type '(c-decl-arg-start
- c-decl-type-start))))))))))
+ (or
+ (and
+ (c-back-over-compound-identifier)
+ (progn
+ (c-backward-syntactic-ws)
+ (or (bobp)
+ (progn
+ (setq type (c-get-char-property (1- (point))
+ 'c-type))
+ (memq type '(c-decl-arg-start
+ c-decl-type-start))))))
+ (and (zerop (c-backward-token-2))
+ (looking-at c-fun-name-substitute-key))))))))
(cons 'decl nil))
(t (cons 'arglist t)))))
@@ -1354,9 +1400,12 @@ casts and declarations are fontified. Used on level 2 and higher."
'c-decl-type-start
'c-decl-id-start)))))
(c-font-lock-declarators
- (min limit (point-max)) decl-list
+ (min limit (point-max))
+ decl-list
(not (null (cadr decl-or-cast)))
- (not toplev) template-class))
+ (not toplev)
+ template-class
+ (memq context '(decl <>))))
;; A declaration has been successfully identified, so do all the
;; fontification of types and refs that've been recorded.
@@ -1909,6 +1958,163 @@ casts and declarations are fontified. Used on level 2 and higher."
(forward-char))))) ; over the terminating "]" or other close paren.
nil)
+(defun c-forward-c++-module-name (limit)
+ ;; Is there a C++20 module name at point? If so, return a cons of the start
+ ;; and end of that name, in which case point will be moved over the name and
+ ;; following whitespace. Otherwise nil will be returned and point will be
+ ;; unmoved. This function doesn't regard a partition as part of the name.
+ ;; The entire construct must end not after LIMIT.
+ (when (and
+ (looking-at c-module-name-re)
+ (<= (match-end 0) limit)
+ (not (looking-at c-keywords-regexp)))
+ (goto-char (match-end 0))
+ (prog1 (cons (match-beginning 0) (match-end 0))
+ (c-forward-syntactic-ws limit))))
+
+(defun c-forward-c++-module-partition-name (limit)
+ ;; Is there a C++20 module partition name (starting with its colon) at
+ ;; point? If so return a cons of the start and end of the name, not
+ ;; including the colon, in which case point will be move to after the name
+ ;; and following whitespace. Otherwise nil will be returned and point not
+ ;; moved. The entire construct must end not after LIMIT.
+ (when (and
+ (eq (char-after) ?:)
+ (progn
+ (forward-char)
+ (c-forward-syntactic-ws limit)
+ (looking-at c-module-name-re))
+ (<= (match-end 0) limit)
+ (not (looking-at c-keywords-regexp)))
+ (goto-char (match-end 0))
+ (prog1 (cons (match-beginning 0) (match-end 0))
+ (c-forward-syntactic-ws limit))))
+
+(defun c-font-lock-c++-modules (limit)
+ ;; Fontify the C++20 module stanzas, characterized by the keywords `module',
+ ;; `export' and `import'. Note that this has to be done by a function (as
+ ;; opposed to regexps) due to the presence of optional C++ attributes.
+ ;;
+ ;; This function will be called from font-lock for a region bounded by POINT
+ ;; and LIMIT, as though it were to identify a keyword for
+ ;; font-lock-keyword-face. It always returns NIL to inhibit this and
+ ;; prevent a repeat invocation. See elisp/lispref page "Search-based
+ ;; Fontification".
+ (while (and (< (point) limit)
+ (re-search-forward
+ "\\<\\(module\\|export\\|import\\)\\>\\(?:[^_$]\\|$\\)"
+ limit t))
+ (goto-char (match-end 1))
+ (let (name-bounds pos beg end
+ module-names) ; A list of conses of start and end
+ ; of pertinent module names
+ (unless (c-skip-comments-and-strings limit)
+ (when
+ (cond
+ ;; module foo...; Note we don't handle module; or module
+ ;; :private; here, since they don't really need handling.
+ ((save-excursion
+ (when (equal (match-string-no-properties 1) "export")
+ (c-forward-syntactic-ws limit)
+ (re-search-forward "\\=\\(module\\)\\>\\(?:[^_$]\\|$\\)"
+ limit t))
+ (and (equal (match-string-no-properties 1) "module")
+ (< (point) limit)
+ (progn (c-forward-syntactic-ws limit)
+ (setq name-bounds (c-forward-c++-module-name
+ limit)))
+ (setq pos (point))))
+ (push name-bounds module-names)
+ (goto-char pos)
+ ;; Is there a partition name?
+ (when (setq name-bounds (c-forward-c++-module-partition-name
+ limit))
+ (push name-bounds module-names))
+ t)
+
+ ;; import
+ ((save-excursion
+ (when (equal (match-string-no-properties 1) "export")
+ (c-forward-syntactic-ws limit)
+ (re-search-forward "\\=\\(import\\)\\>\\(?:[^_$]\\|$\\)"
+ limit t))
+ (and (equal (match-string-no-properties 1) "import")
+ (< (point) limit)
+ (progn (c-forward-syntactic-ws limit)
+ (setq pos (point)))))
+ (goto-char pos)
+ (cond
+ ;; import foo;
+ ((setq name-bounds (c-forward-c++-module-name limit))
+ (push name-bounds module-names)
+ t)
+ ;; import :foo;
+ ((setq name-bounds (c-forward-c++-module-partition-name limit))
+ (push name-bounds module-names)
+ t)
+ ;; import "foo";
+ ((and (eq (char-after) ?\")
+ (setq pos (point))
+ (c-safe (c-forward-sexp) t)) ; Should already have string face.
+ (when (eq (char-before) ?\")
+ (setq beg pos
+ end (point)))
+ (c-forward-syntactic-ws limit)
+ t)
+ ;; import <foo>;
+ ((and (looking-at "<\\(?:\\\\.\\|[^\\\n\r\t>]\\)*\\(>\\)?")
+ (< (match-end 0) limit))
+ (setq beg (point))
+ (goto-char (match-end 0))
+ (when (match-end 1)
+ (setq end (point)))
+ (if (featurep 'xemacs)
+ (c-put-font-lock-face
+ (1+ beg) (if end (1- end) (point)) font-lock-string-face)
+ (c-put-font-lock-face
+ beg (or end (point)) font-lock-string-face))
+ (c-forward-syntactic-ws limit)
+ t)
+ (t nil)))
+
+ ;; export
+ ;; There is no fontification to be done here, but we need to
+ ;; skip over the declaration or declaration sequence.
+ ((save-excursion
+ (when (equal (match-string-no-properties 0) "export")
+ (c-forward-syntactic-ws limit)
+ (setq pos (point))))
+ (goto-char (point))
+ (if (eq (char-after) ?{)
+ ;; Declaration sequence.
+ (unless (and (c-go-list-forward nil limit)
+ (eq (char-before) ?}))
+ (goto-char limit)
+ nil)
+ ;; Single declaration
+ (unless (c-end-of-decl-1)
+ (goto-char limit)
+ nil)))) ; Nothing more to do, here.
+
+ ;; Optional attributes?
+ (while (and (c-looking-at-c++-attribute)
+ (< (match-end 0) limit))
+ (goto-char (match-end 0))
+ (c-forward-syntactic-ws limit))
+ ;; Finally, there must be a semicolon.
+ (if (and (< (point) limit)
+ (eq (char-after) ?\;))
+ (progn
+ (forward-char)
+ ;; Fontify any module names we've encountered.
+ (dolist (name module-names)
+ (c-put-font-lock-face (car name) (cdr name)
+ c-reference-face-name)))
+ ;; No semicolon, so put warning faces on any delimiters.
+ (when beg
+ (c-put-font-lock-face beg (1+ beg) font-lock-warning-face))
+ (when end
+ (c-put-font-lock-face (1- end) end font-lock-warning-face))))))))
(c-lang-defconst c-simple-decl-matchers
"Simple font lock matchers for types and declarations. These are used
@@ -2289,8 +2495,12 @@ higher."
(widen)
(goto-char (point-min))
(while (re-search-forward target-re nil t)
- (put-text-property (match-beginning 0) (match-end 0)
- 'fontified nil)
+ (when (and
+ (get-text-property (match-beginning 0) 'fontified)
+ (not (memq (c-get-char-property (match-beginning 0) 'face)
+ c-literal-faces)))
+ (c-put-font-lock-face (match-beginning 0) (match-end 0)
+ font-lock-type-face))
(dolist (win-boundary window-boundaries)
(when (and (< (match-beginning 0) (cdr win-boundary))
(> (match-end 0) (car win-boundary))
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 068b4a65b21..b17718cfd54 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -93,7 +93,7 @@
;; definitions (i.e. this file and/or cc-fonts.el) if necessary.
;;
;; A small example of a derived mode is available at
-;; <http://cc-mode.sourceforge.net/derived-mode-ex.el>. It also
+;; <https://cc-mode.sourceforge.net/derived-mode-ex.el>. It also
;; contains some useful hints for derived mode developers.
;;; Using language variables:
@@ -456,6 +456,7 @@ so that all identifiers are recognized as words.")
c-depropertize-CPP
c-before-change-check-ml-strings
c-before-change-check-<>-operators
+ c-before-after-change-check-c++-modules
c-truncate-bs-cache
c-before-change-check-unbalanced-strings
c-parse-quotes-before-change
@@ -516,6 +517,7 @@ parameters \(point-min) and \(point-max).")
c-parse-quotes-after-change
c-after-change-mark-abnormal-strings
c-extend-font-lock-region-for-macros
+ c-before-after-change-check-c++-modules
c-neutralize-syntax-in-CPP
c-restore-<>-properties
c-change-expand-fl-region)
@@ -932,6 +934,8 @@ This value is by default merged into `c-operators'."
t)))
(when ops
(c-make-keywords-re 'appendable ops))))
+(c-lang-defvar c-opt-identifier-prefix-key
+ (c-lang-const c-opt-identifier-prefix-key))
(c-lang-defconst c-after-id-concat-ops
"Operators that can occur after a binary operator on `c-identifier-ops'
@@ -1018,6 +1022,16 @@ e.g. identifiers with template arguments such as \"A<X,Y>\" in C++."
"")))
(c-lang-defvar c-identifier-key (c-lang-const c-identifier-key))
+(c-lang-defconst c-module-name-re
+ "This regexp matches (a component of) a module name.
+Currently (2022-09) just C++ Mode uses this."
+ t nil
+ c++ (concat (c-lang-const c-symbol-key)
+ "\\(?:\\."
+ (c-lang-const c-symbol-key)
+ "\\)*"))
+(c-lang-defvar c-module-name-re (c-lang-const c-module-name-re))
+
(c-lang-defconst c-identifier-last-sym-match
;; This was a docstring constant in 5.30 but it's no longer used.
;; It's only kept to avoid breaking third party code.
@@ -1316,6 +1330,10 @@ since CC Mode treats every identifier as an expression."
,@(when (c-major-mode-is 'java-mode)
'(">>>")))
+ ;; The C++ "spaceship" operator.
+ ,@(when (c-major-mode-is 'c++-mode)
+ `((left-assoc "<=>")))
+
;; Relational.
(left-assoc "<" ">" "<=" ">="
,@(when (c-major-mode-is 'java-mode)
@@ -1429,10 +1447,9 @@ form\". See also `c-op-identifier-prefix'."
"^" "??'" "xor" "&" "bitand" "|" "??!" "bitor" "~" "??-" "compl"
"!" "=" "<" ">" "+=" "-=" "*=" "/=" "%=" "^="
"??'=" "xor_eq" "&=" "and_eq" "|=" "??!=" "or_eq"
- "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=" ">="
+ "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=>" "<=" ">="
"&&" "and" "||" "??!??!" "or" "++" "--" "," "->*" "->"
- "()" "[]" "<::>" "??(??)")
- ;; These work like identifiers in Pike.
+ "()" "[]" "\"\"" "<::>" "??(??)")
pike '("`+" "`-" "`&" "`|" "`^" "`<<" "`>>" "`*" "`/" "`%" "`~"
"`==" "`<" "`>" "`!" "`[]" "`[]=" "`->" "`->=" "`()" "``+"
"``-" "``&" "``|" "``^" "``<<" "``>>" "``*" "``/" "``%"
@@ -1551,8 +1568,10 @@ operators."
"List of all arithmetic operators, including \"+=\", etc."
;; Note: in the following, there are too many operators for AWK and IDL.
t (append (c-lang-const c-assignment-operators)
- '("+" "-" "*" "/" "%"
+ `("+" "-" "*" "/" "%"
"<<" ">>"
+ ,@(if (c-major-mode-is 'c++-mode)
+ '("<=>"))
"<" ">" "<=" ">="
"==" "!="
"&" "^" "|"
@@ -2202,7 +2221,7 @@ the appropriate place for that."
'("_Bool" "_Complex" "_Imaginary") ; Conditionally defined in C99.
(c-lang-const c-primitive-type-kwds))
c++ (append
- '("bool" "wchar_t" "char16_t" "char32_t")
+ '("bool" "wchar_t" "char8_t" "char16_t" "char32_t")
(c-lang-const c-primitive-type-kwds))
;; Objective-C extends C, but probably not the new stuff in C99.
objc (append
@@ -2581,6 +2600,35 @@ will be handled."
t (c-make-keywords-re t (c-lang-const c-equals-type-clause-kwds)))
(c-lang-defvar c-equals-type-clause-key (c-lang-const c-equals-type-clause-key))
+(c-lang-defconst c-equals-nontype-decl-kwds
+ "Keywords which are followed by an identifier then an \"=\"
+sign, which declares the identifier to be something other than a
+type."
+ t nil
+ c++ '("concept"))
+
+(c-lang-defconst c-equals-nontype-decl-key
+ ;; An unadorned regular expression which matches any member of
+ ;; `c-equals-decl-kwds', or nil if such don't exist in the current language.
+ t (when (c-lang-const c-equals-nontype-decl-kwds)
+ (c-make-keywords-re nil (c-lang-const c-equals-nontype-decl-kwds))))
+(c-lang-defvar c-equals-nontype-decl-key
+ (c-lang-const c-equals-nontype-decl-key))
+
+(c-lang-defconst c-fun-name-substitute-kwds
+ "Keywords which take the place of type+declarator at the beginning
+of a function-like structure, such as a C++20 \"requires\"
+clause. An arglist may or may not follow such a keyword."
+ t nil
+ c++ '("requires"))
+
+(c-lang-defconst c-fun-name-substitute-key
+ ;; An adorned regular expression which matches any member of
+ ;; `c-fun-name-substitute-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-fun-name-substitute-kwds)))
+(c-lang-defvar c-fun-name-substitute-key
+ (c-lang-const c-fun-name-substitute-key))
+
(c-lang-defconst c-modifier-kwds
"Keywords that can prefix normal declarations of identifiers
\(and typically act as flags). Things like argument declarations
@@ -2594,8 +2642,8 @@ will be handled."
t nil
(c c++) '("extern" "inline" "register" "static")
c (append '("auto") (c-lang-const c-modifier-kwds))
- c++ (append '("constexpr" "explicit" "friend" "mutable" "template"
- "thread_local" "virtual")
+ c++ (append '("consteval" "constexpr" "constinit" "explicit"
+ "friend" "mutable" "template" "thread_local" "virtual")
;; "using" is now handled specially (2020-09-14).
(c-lang-const c-modifier-kwds))
objc '("auto" "bycopy" "byref" "extern" "in" "inout" "oneway" "out" "static")
@@ -2624,6 +2672,7 @@ If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled."
t nil
+ c++ '("export")
objc '("@class" "@defs" "@end" "@property" "@dynamic" "@synthesize"
"@compatibility_alias")
java '("import" "package")
@@ -2669,7 +2718,8 @@ one of `c-type-list-kwds', `c-ref-list-kwds',
(c c++) '(;; GCC extension.
"__attribute__"
;; MSVC extension.
- "__declspec"))
+ "__declspec")
+ c++ (append (c-lang-const c-decl-hangon-kwds) '("alignas")))
(c-lang-defconst c-decl-hangon-key
;; Adorned regexp matching `c-decl-hangon-kwds'.
@@ -2885,6 +2935,15 @@ regexp if `c-colon-type-list-kwds' isn't nil."
"[^][{}();,/#=:]*:")))
(c-lang-defvar c-colon-type-list-re (c-lang-const c-colon-type-list-re))
+(c-lang-defconst c-sub-colon-type-list-re
+ "Regexp matching buffer content that may come between a keyword in
+`c-colon-type-list-kwds' and a putative colon, or nil if there are no
+such keywords. Exception: it does not match any C++ attributes."
+ t (if (c-lang-const c-colon-type-list-re)
+ (substring (c-lang-const c-colon-type-list-re) 0 -1)))
+(c-lang-defvar c-sub-colon-type-list-re
+ (c-lang-const c-sub-colon-type-list-re))
+
(c-lang-defconst c-paren-nontype-kwds
"Keywords that may be followed by a parenthesis expression that doesn't
contain type identifiers."
@@ -2893,7 +2952,7 @@ contain type identifiers."
"__attribute__"
;; MSVC extension.
"__declspec")
- c++ (append (c-lang-const c-paren-nontype-kwds) '("noexcept")))
+ c++ (append (c-lang-const c-paren-nontype-kwds) '("noexcept" "alignas")))
(c-lang-defconst c-paren-nontype-key
t (c-make-keywords-re t (c-lang-const c-paren-nontype-kwds)))
@@ -2925,6 +2984,17 @@ if this isn't nil."
;; In CORBA PSDL:
"ref"))
+(c-lang-defconst c-pre-concept-<>-kwds
+ "Keywords that may be followed by an angle bracket expression containing
+uses of \"concepts\". This is currently (2022-09) used only by C++."
+ t nil
+ c++ '("template"))
+
+(c-lang-defconst c-pre-concept-<>-key
+ ;; Regexp matching any element of `c-pre-concept-<>-kwds'.
+ t (c-make-keywords-re t (c-lang-const c-pre-concept-<>-kwds)))
+(c-lang-defvar c-pre-concept-<>-key (c-lang-const c-pre-concept-<>-key))
+
(c-lang-defconst c-<>-arglist-kwds
"Keywords that can be followed by a C++ style template arglist; see
`c-recognize-<>-arglists' for details. That language constant is
@@ -2937,7 +3007,8 @@ assumed to be set if this isn't nil."
(c-lang-defconst c-<>-sexp-kwds
;; All keywords that can be followed by an angle bracket sexp.
t (c--delete-duplicates (append (c-lang-const c-<>-type-kwds)
- (c-lang-const c-<>-arglist-kwds))
+ (c-lang-const c-<>-arglist-kwds)
+ (c-lang-const c-import-<>-kwds))
:test 'string-equal))
(c-lang-defconst c-opt-<>-sexp-key
@@ -3099,6 +3170,25 @@ This construct is \"<keyword> <expression> :\"."
idl nil
awk nil)
+(c-lang-defconst c-import-<>-kwds
+ "Keywords which can start an expression like \"import <...>\" in C++20.
+The <, and > operators are like those of #include <...>, they are
+not really template operators."
+ t nil
+ c++ '("import"))
+
+(c-lang-defconst c-module-kwds
+ "The keywords which introduce module constructs in C++20 onwards."
+ t nil
+ c++ '("module" "import" "export"))
+
+(c-lang-defconst c-module-key
+ ;; Adorned regexp matching module declaration keywords, or nil if there are
+ ;; none.
+ t (if (c-lang-const c-module-kwds)
+ (c-make-keywords-re t (c-lang-const c-module-kwds))))
+(c-lang-defvar c-module-key (c-lang-const c-module-key))
+
(c-lang-defconst c-constant-kwds
"Keywords for constants."
t nil
@@ -3113,6 +3203,10 @@ This construct is \"<keyword> <expression> :\"."
java '("true" "false" "null") ; technically "literals", not keywords
pike '("UNDEFINED")) ;; Not a keyword, but practically works as one.
+(c-lang-defconst c-constant-key
+ t (c-make-keywords-re t (c-lang-const c-constant-kwds)))
+(c-lang-defvar c-constant-key (c-lang-const c-constant-key))
+
(c-lang-defconst c-primary-expr-kwds
"Keywords besides constants and operators that start primary expressions."
t nil
@@ -3748,7 +3842,10 @@ is in effect when this is matched (see `c-identifier-syntax-table')."
;; "throw" in `c-type-modifier-kwds' is followed
;; by a parenthesis list, but no extra measures
;; are necessary to handle that.
- (regexp-opt (c-lang-const c-type-modifier-kwds) t)
+ (regexp-opt
+ (append (c-lang-const c-fun-name-substitute-kwds)
+ (c-lang-const c-type-modifier-kwds))
+ t)
"\\>")
"")
"\\)")
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 9309a546dbd..dce300f33c9 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -66,12 +66,12 @@
;; You can get the latest version of CC Mode, including PostScript
;; documentation and separate individual files from:
;;
-;; http://cc-mode.sourceforge.net/
+;; https://cc-mode.sourceforge.net/
;;
;; You can join a moderated CC Mode announcement-only mailing list by
;; visiting
;;
-;; http://lists.sourceforge.net/mailman/listinfo/cc-mode-announce
+;; https://lists.sourceforge.net/mailman/listinfo/cc-mode-announce
;; Externally maintained major modes which use CC-mode's engine include:
;; - cuda-mode
@@ -172,7 +172,7 @@
;; `c-font-lock-init' too to set up CC Mode's font lock support.
;;
;; See cc-langs.el for further info. A small example of a derived mode
-;; is also available at <http://cc-mode.sourceforge.net/
+;; is also available at <https://cc-mode.sourceforge.net/
;; derived-mode-ex.el>.
(defun c-leave-cc-mode-mode ()
@@ -1421,6 +1421,13 @@ Note that the style variables are always made local to the buffer."
(c-clear-syn-tab (point)))
(t (c-benign-error "c-remove-string-fences: Wrong position")))))
+(defvar c-open-string-opener nil
+ "The position of the opening delimiter of an unterminated string or nil.
+This is valid only immediately after a buffer change, and refers
+only to an opener in the (logical) line containing the END
+position of `after-change-functions'.")
+(make-variable-buffer-local 'c-open-string-opener)
+
(defun c-before-change-check-unbalanced-strings (beg end)
;; If BEG or END is inside an unbalanced string, remove the syntax-table
;; text property from respectively the start or end of the string. Also
@@ -1685,13 +1692,14 @@ Note that the style variables are always made local to the buffer."
(c-put-syn-tab (1- (point)) '(15))
(c-put-syn-tab (match-end 0) '(15))
(setq c-new-BEG (min c-new-BEG (point))
- c-new-END (max c-new-END (match-end 0))))
+ c-new-END (max c-new-END (match-end 0)))
+ (setq c-open-string-opener (1- (point))))
((or (eq (match-end 0) (point-max))
(eq (char-after (match-end 0)) ?\\)) ; \ at EOB
(c-put-syn-tab (1- (point)) '(15))
(setq c-new-BEG (min c-new-BEG (point))
c-new-END (max c-new-END (match-end 0))) ; Do we need c-new-END?
- ))
+ (setq c-open-string-opener (1- (point)))))
(goto-char (min (1+ (match-end 0)) (point-max))))
(setq s nil)))))
@@ -2130,6 +2138,7 @@ with // and /*, not more generic line and block comments."
;; (c-new-BEG c-new-END) will be the region to fontify.
(setq c-new-BEG beg c-new-END end)
(setq c-maybe-stale-found-type nil)
+ (setq c-open-string-opener nil)
;; A workaround for syntax-ppss's failure to notice syntax-table text
;; property changes.
(when (fboundp 'syntax-ppss)
@@ -2394,7 +2403,7 @@ with // and /*, not more generic line and block comments."
(setq pseudo (c-cheap-inside-bracelist-p (c-parse-state)))))))
(goto-char pseudo))
t)
- (> (point) bod-lim)
+ (>= (point) bod-lim)
(progn (c-forward-syntactic-ws)
;; Have we got stuck in a comment at EOB?
(not (and (eobp)
@@ -2418,7 +2427,8 @@ with // and /*, not more generic line and block comments."
(and (> (point) bod-lim)
(or (memq (char-before) '(?\( ?\[))
(and (eq (char-before) ?\<)
- (eq (c-get-char-property
+ (equal
+ (c-get-char-property
(1- (point)) 'syntax-table)
c-<-as-paren-syntax))
(and (eq (char-before) ?{)
@@ -2448,9 +2458,12 @@ with // and /*, not more generic line and block comments."
(goto-char pos)
(let ((lit-start (c-literal-start))
(lim (c-determine-limit 1000))
- enclosing-attribute pos1)
+ enclosing-attribute pos1 ml-delim)
(if lit-start
(goto-char lit-start))
+ (when (and lit-start c-ml-string-opener-re
+ (setq ml-delim (c-ml-string-opener-around-point)))
+ (goto-char (car ml-delim)))
(c-backward-syntactic-ws lim)
(when (setq enclosing-attribute (c-enclosing-c++-attribute))
(goto-char (car enclosing-attribute)) ; Only happens in C++ Mode.
@@ -2461,38 +2474,43 @@ with // and /*, not more generic line and block comments."
(c-backward-syntactic-ws lim))
(when (setq pos1 (c-on-identifier))
(goto-char pos1)
- (let ((lim (save-excursion
- (and (c-beginning-of-macro)
- (progn (c-end-of-macro) (point))))))
- (and (c-forward-declarator lim)
- (if (and (eq (char-after) ?\()
- (c-go-list-forward nil lim))
- (and
- (progn (c-forward-syntactic-ws lim)
- (not (eobp)))
- (progn
- (if (looking-at c-symbol-char-key)
- ;; Deal with baz (foo((bar)) type var), where
- ;; foo((bar)) is not semantically valid. The result
- ;; must be after var).
- (and
- (goto-char pos)
- (setq pos1 (c-on-identifier))
- (goto-char pos1)
- (progn
- (c-backward-syntactic-ws lim)
- (eq (char-before) ?\())
- (c-fl-decl-end (1- (point))))
- (c-backward-syntactic-ws lim)
- (point))))
- (if (progn (c-forward-syntactic-ws lim)
- (not (eobp)))
- (c-forward-over-token)
- (let ((lit-start (c-literal-start)))
- (when lit-start
- (goto-char lit-start))
- (c-backward-syntactic-ws)))
- (and (>= (point) pos) (point))))))))
+ (let* ((lim1 (save-excursion
+ (and (c-beginning-of-macro)
+ (progn (c-end-of-macro) (point)))))
+ (decl-res (c-forward-declarator)))
+ (if (or (cadr (cddr (cddr decl-res))) ; We scanned an arglist.
+ (and (eq (char-after) ?\() ; Move over a non arglist (...).
+ (prog1 (c-go-list-forward)
+ (c-forward-syntactic-ws))))
+ (if (looking-at c-symbol-char-key)
+ ;; Deal with baz (foo((bar)) type var), where `pos'
+ ;; was inside foo, but foo((bar)) is not semantically
+ ;; valid. The result must be after var).
+ (and
+ (goto-char pos)
+ (setq pos1 (c-on-identifier))
+ (goto-char pos1)
+ (progn
+ (c-backward-syntactic-ws lim1)
+ (eq (char-before) ?\())
+ (c-fl-decl-end (1- (point))))
+ (c-forward-over-token)
+ (point))
+ (if (progn (c-forward-syntactic-ws)
+ (not (eobp)))
+ (progn
+ (c-forward-over-token)
+ ;; Cope with having POS withing a syntactically invalid
+ ;; (...), by moving backward out of the parens and trying
+ ;; again.
+ (when (and (eq (char-before) ?\))
+ (c-go-list-backward (point) lim1))
+ (c-fl-decl-end (point))))
+ (let ((lit-start (c-literal-start)))
+ (when lit-start
+ (goto-char lit-start))
+ (c-backward-syntactic-ws)))
+ (and (>= (point) pos) (point)))))))
(defun c-change-expand-fl-region (_beg _end _old-len)
;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock
@@ -2698,11 +2716,9 @@ This function is called from `c-common-init', once per mode initialization."
At the time of call, point is just after the newly inserted CHAR.
When CHAR is \" and not within a comment, t will be returned if
-the quotes on the current line are already balanced (i.e. if the
-last \" is not marked with a string fence syntax-table text
-property). For other cases, the default value of
-`electric-pair-inhibit-predicate' is called and its value
-returned.
+the quotes on the current line are already balanced. For other
+cases, the default value of `electric-pair-inhibit-predicate' is
+called and its value returned.
This function is the appropriate value of
`electric-pair-inhibit-predicate' for CC Mode modes, which mark
@@ -2710,11 +2726,7 @@ invalid strings with such a syntax table text property on the
opening \" and the next unescaped end of line."
(if (and (eq char ?\")
(not (memq (cadr (c-semi-pp-to-literal (1- (point)))) '(c c++))))
- (let ((last-quote (save-match-data
- (save-excursion
- (goto-char (c-point 'eoll))
- (search-backward "\"")))))
- (not (equal (c-get-char-property last-quote 'c-fl-syn-tab) '(15))))
+ (not c-open-string-opener)
(funcall (default-value 'electric-pair-inhibit-predicate) char)))
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 5ce80e06577..6473b507785 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -980,12 +980,17 @@ Faces `compilation-error-face', `compilation-warning-face',
"Face name to use for leaving directory messages.")
(defcustom compilation-auto-jump-to-first-error nil
- "If non-nil, automatically jump to the first error during compilation."
+ "If non-nil, automatically jump to the first error during compilation.
+
+The value `if-location-known' means automatically jump to the first error
+if the error's file can be found. The value `first-known' means jump to
+the first error whose file can be found. Any other non-nil value means
+jump to the first error unconditionally."
:type '(choice (const :tag "Never" nil)
(const :tag "Always" t)
(const :tag "If location known" if-location-known)
(const :tag "First known location" first-known))
- :version "23.1")
+ :version "29.1")
(defvar-local compilation-auto-jump-to-next nil
"If non-nil, automatically jump to the next error encountered.")
@@ -1235,10 +1240,10 @@ POS and RES.")
(if win (set-window-point win pos)))
(when compilation-auto-jump-to-first-error
(cl-case compilation-auto-jump-to-first-error
- ('if-location-known
+ (if-location-known
(when (compilation--file-known-p)
(compile-goto-error)))
- ('first-known
+ (first-known
(let (match)
(while (and (not (compilation--file-known-p))
(setq match (text-property-search-forward
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index a3995e2969d..539b2771490 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -2,7 +2,7 @@
;; Copyright (C) 1985-2022 Free Software Foundation, Inc.
-;; Author: Ilya Zakharevich
+;; Author: Ilya Zakharevich <ilyaz@cpan.org>
;; Bob Olson
;; Jonathan Rockway <jon@jrock.us>
;; Maintainer: emacs-devel@gnu.org
@@ -24,8 +24,6 @@
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-;; Corrections made by Ilya Zakharevich ilyaz@cpan.org
-
;;; Commentary:
;; You can either fine-tune the bells and whistles of this mode or
@@ -54,7 +52,7 @@
;; (define-key global-map [M-S-down-mouse-3] #'imenu)
;; This version supports the syntax added by the MooseX::Declare CPAN
-;; module, as well as Perl 5.10 keyword support.
+;; module, as well as Perl 5.10 keywords.
;;; Code:
@@ -634,7 +632,7 @@ mode-compile.el.
If your Emacs does not default to `cperl-mode' on Perl files, and you
want it to: put the following into your .emacs file:
- (defalias \\='perl-mode \\='cperl-mode)
+ (add-to-list \\='major-mode-remap-alist \\='(perl-mode . cperl-mode))
Get perl5-info from
$CPAN/doc/manual/info/perl5-old/perl5-info.tar.gz
@@ -958,13 +956,6 @@ Unless KEEP, removes the old indentation."
"Abbrev table in use in CPerl mode buffers."
:parents (list cperl-mode-electric-keywords-abbrev-table))
-;; ;; TODO: Commented out as we don't know what it is used for. If
-;; ;; there are no bug reports about this for Emacs 28.1, this
-;; ;; can probably be removed. (Code search online reveals nothing.)
-;; (when (boundp 'edit-var-mode-alist)
-;; ;; FIXME: What package uses this?
-;; (add-to-list 'edit-var-mode-alist '(perl-mode (regexp . "^cperl-"))))
-
(defvar cperl-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "{" 'cperl-electric-lbrace)
@@ -3016,7 +3007,7 @@ and closing parentheses and brackets."
;; Now it is a hash reference
(+ cperl-indent-level cperl-close-paren-offset))
;; Labels do not take :: ...
- (if (looking-at "\\(\\w\\|_\\)+[ \t]*:")
+ (if (looking-at "\\(\\w\\|_\\)+[ \t]*:[^:]")
(if (> (current-indentation) cperl-min-label-indent)
(- (current-indentation) cperl-label-offset)
;; Do not move `parse-data', this should
@@ -3171,7 +3162,7 @@ Returns true if comment is found. In POD will not move the point."
Mark as generic string if STRING, as generic comment otherwise.
A single character is marked as punctuation and directly
fontified. Do nothing if BEGIN and END are equal. If
-`cperl-use-syntax-text-property' is nil, just fontify."
+`cperl-use-syntax-table-text-property' is nil, just fontify."
(if (and cperl-use-syntax-table-text-property
(> end begin))
(progn
@@ -3727,7 +3718,6 @@ This is part of `cperl-find-pods-heres' (below)."
overshoot
warning-message)))
-;; Debugging this may require (setq max-specpdl-size 2000)...
(defun cperl-find-pods-heres (&optional min max non-inter end ignore-max end-of-here-doc)
"Scan the buffer for hard-to-parse Perl constructions.
If `cperl-pod-here-fontify' is non-nil after evaluation,
@@ -6045,39 +6035,6 @@ Style of printout regulated by the variable `cperl-ps-print-face-properties'."
(ps-extend-face-list cperl-ps-print-face-properties)
(ps-print-buffer-with-faces file)))
-;; (defun cperl-ps-print-init ()
-;; "Initialization of `ps-print' components for faces used in CPerl."
-;; ;; Guard against old versions
-;; (defvar ps-underlined-faces nil)
-;; (defvar ps-bold-faces nil)
-;; (defvar ps-italic-faces nil)
-;; (setq ps-bold-faces
-;; (append '(font-lock-emphasized-face
-;; cperl-array-face
-;; font-lock-keyword-face
-;; font-lock-variable-name-face
-;; font-lock-constant-face
-;; font-lock-reference-face
-;; font-lock-other-emphasized-face
-;; cperl-hash-face)
-;; ps-bold-faces))
-;; (setq ps-italic-faces
-;; (append '(cperl-nonoverridable-face
-;; font-lock-constant-face
-;; font-lock-reference-face
-;; font-lock-other-emphasized-face
-;; cperl-hash-face)
-;; ps-italic-faces))
-;; (setq ps-underlined-faces
-;; (append '(font-lock-emphasized-face
-;; cperl-array-face
-;; font-lock-other-emphasized-face
-;; cperl-hash-face
-;; cperl-nonoverridable-face font-lock-type-face)
-;; ps-underlined-faces))
-;; (cons 'font-lock-type-face ps-underlined-faces))
-
-
(cperl-windowed-init)
(defconst cperl-styles-entries
@@ -8366,7 +8323,7 @@ the appropriate statement modifier."
'cperl-short-docs
'variable-documentation))))
(Man-switches "")
- (manual-program (if is-func "perldoc -f" "perldoc")))
+ (manual-program (concat "perldoc -i" (if is-func " -f"))))
(Man-getpage-in-background word)))
;;;###autoload
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 4ada27a1aca..7e7ea6aeb9e 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -220,8 +220,8 @@ All commands in `lisp-mode-shared-map' are inherited by this map."
Load the compiled code when finished.
Use `emacs-lisp-byte-compile-and-load' in combination with
-`native-comp-deferred-compilation' set to t to achieve asynchronous
-native compilation."
+`inhibit-automatic-native-compilation' set to nil to achieve
+asynchronous native compilation."
(interactive nil emacs-lisp-mode)
(emacs-lisp--before-compile-buffer)
(load (native-compile buffer-file-name)))
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index db2c8efbd40..85c5992998a 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -1784,10 +1784,10 @@ Bind `case-fold-search' during the evaluation, depending on the value of
(defun tags--compat-initialize (initialize)
(fileloop-initialize
(tags--compat-files initialize)
+ (lambda () (tags-loop-eval tags-loop-scan))
(if tags-loop-operate
(lambda () (tags-loop-eval tags-loop-operate))
- (lambda () (message "Scanning file %s...found" buffer-file-name) nil))
- (lambda () (tags-loop-eval tags-loop-scan))))
+ (lambda () (message "Scanning file %s...found" buffer-file-name) nil))))
;;;###autoload
(defun tags-loop-continue (&optional first-time)
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 15ee5cb7d51..5bbbfa822fd 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -1538,7 +1538,7 @@ POS can be a buffer position or a button"
(flymake-show-diagnostic (if (button-type pos) (button-start pos) pos))))
(defun flymake--tabulated-entries-1 (diags project-root)
- "Helper for `flymake--diagnostic-buffer-entries'.
+ "Helper for `flymake--diagnostics-buffer-entries'.
PROJECT-ROOT indicates that each entry should be preceded by the
filename of the diagnostic relative to that directory."
(cl-loop
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 6e8032b7eae..0de3d213a4d 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -966,7 +966,7 @@ detailed description of this mode.
(if gdb-active-process
(gdb-gud-context-command "-exec-continue")
"-exec-run")))
- "C-v" "Start or continue execution. Use a prefix to specify arguments.")
+ "\C-v" "Start or continue execution. Use a prefix to specify arguments.")
;; For debugging Emacs only.
(gud-def gud-pp
diff --git a/lisp/progmodes/glasses.el b/lisp/progmodes/glasses.el
index c7b05873369..c0bd6f220c9 100644
--- a/lisp/progmodes/glasses.el
+++ b/lisp/progmodes/glasses.el
@@ -84,12 +84,22 @@ performed."
(defcustom glasses-face nil
- "Face to be put on capitals of an identifier looked through glasses.
-If it is nil, no face is placed at the capitalized letter.
+ "Face to use for capital letters of identifiers where separators were added.
+If it is nil, the capital letters will display with their usual faces.
For example, you can set `glasses-separator' to an empty string and
`glasses-face' to `bold'. Then unreadable identifiers will have no separators,
-but will have their capitals in bold."
+but will have their capitals in bold.
+
+As another example, you may wish to have a clear visual indication of
+where the `glasses-separator' string was inserted by `glasses-mode',
+as opposed to where they are part of the original identifiers. This
+can be useful when the program source code uses mixed CamelCase and
+normal_readable identifiers, and you want to know which underscores
+were added by this mode. Customizing this face to something like `bold'
+will show the capital letters following the inserted `glasses-separator'
+in a distinct face. Note that you must use `customize-variable' for
+changing the face; just assigning the value has no effect."
:type '(choice (const :tag "None" nil) face)
:set 'glasses-custom-set
:initialize 'custom-initialize-default)
diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el
index 53788949ea4..767216c03f2 100644
--- a/lisp/progmodes/hideif.el
+++ b/lisp/progmodes/hideif.el
@@ -405,7 +405,7 @@ overlays created."
;; hidden with `hide-ifdef-lines' equals to nil while another part with 't,
;; this case happens.
;; TODO: Should we merge? or just create a container overlay? -- this can
- ;; prevent `hideif-show-ifdef' expanding too many hidden contents since there
+ ;; prevent `show-ifdefs' expanding too many hidden contents since there
;; is only a big overlay exists there without any smaller overlays.
(save-restriction
(widen) ; Otherwise `point-min' and `point-max' will be restricted and thus
@@ -725,7 +725,7 @@ Assuming we've just regexp-matched with `hif-decfloat-regexp' and it matched.
if REMATCH is t, do a rematch."
;; In elisp `(string-to-number "01.e2")' will return 1 instead of the expected
;; 100.0; therefore we need to write our own.
- ;; This function relies on the regexp groups of `hif-dexfloat-regexp'
+ ;; This function relies on the regexp groups of `hif-hexfloat-regexp'
(if (or fix exp)
(setq fix (hif-delete-char-in-string ?' fix)
exp (hif-delete-char-in-string ?' exp))
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index c0796fc2eeb..6de079f05a6 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -3,7 +3,7 @@
;; Copyright (C) 1994-2022 Free Software Foundation, Inc.
;; Author: Thien-Thi Nguyen <ttn@gnu.org>
-;; Dan Nicolaescu <dann@ics.uci.edu>
+;; Dan Nicolaescu <dann@gnu.org>
;; Keywords: C C++ java lisp tools editing comments blocks hiding outlines
;; Maintainer-Version: 5.65.2.2
;; Time-of-Day-Author-Most-Likely-to-be-Recalcitrant: early morning
@@ -256,7 +256,7 @@ This has effect only if `search-invisible' is set to `open'."
;;;###autoload
(defvar hs-special-modes-alist
- (mapcar 'purecopy
+ (mapcar #'purecopy
'((c-mode "{" "}" "/[*/]" nil nil)
(c++-mode "{" "}" "/[*/]" nil nil)
(bibtex-mode ("@\\S(*\\(\\s(\\)" 1))
@@ -351,17 +351,17 @@ Use the command `hs-minor-mode' to toggle or set this variable.")
(defvar hs-minor-mode-map
(let ((map (make-sparse-keymap)))
;; These bindings roughly imitate those used by Outline mode.
- (define-key map "\C-c@\C-h" 'hs-hide-block)
- (define-key map "\C-c@\C-s" 'hs-show-block)
- (define-key map "\C-c@\C-\M-h" 'hs-hide-all)
- (define-key map "\C-c@\C-\M-s" 'hs-show-all)
- (define-key map "\C-c@\C-l" 'hs-hide-level)
- (define-key map "\C-c@\C-c" 'hs-toggle-hiding)
- (define-key map "\C-c@\C-a" 'hs-show-all)
- (define-key map "\C-c@\C-t" 'hs-hide-all)
- (define-key map "\C-c@\C-d" 'hs-hide-block)
- (define-key map "\C-c@\C-e" 'hs-toggle-hiding)
- (define-key map [(shift mouse-2)] 'hs-toggle-hiding)
+ (define-key map "\C-c@\C-h" #'hs-hide-block)
+ (define-key map "\C-c@\C-s" #'hs-show-block)
+ (define-key map "\C-c@\C-\M-h" #'hs-hide-all)
+ (define-key map "\C-c@\C-\M-s" #'hs-show-all)
+ (define-key map "\C-c@\C-l" #'hs-hide-level)
+ (define-key map "\C-c@\C-c" #'hs-toggle-hiding)
+ (define-key map "\C-c@\C-a" #'hs-show-all)
+ (define-key map "\C-c@\C-t" #'hs-hide-all)
+ (define-key map "\C-c@\C-d" #'hs-hide-block)
+ (define-key map "\C-c@\C-e" #'hs-toggle-hiding)
+ (define-key map [(shift mouse-2)] #'hs-toggle-hiding)
map)
"Keymap for hideshow minor mode.")
@@ -778,14 +778,20 @@ region (point MAXP)."
(defmacro hs-life-goes-on (&rest body)
"Evaluate BODY forms if variable `hs-minor-mode' is non-nil.
-In the dynamic context of this macro, `inhibit-point-motion-hooks'
-and `case-fold-search' are both t."
+In the dynamic context of this macro, `case-fold-search' is t."
(declare (debug t))
`(when hs-minor-mode
- (let ((inhibit-point-motion-hooks t)
- (case-fold-search t))
+ (let ((case-fold-search t))
,@body)))
+(defun hs-find-block-beginning-match ()
+ "Reposition point at the end of match of the block-start regexp.
+Return point, or nil if original point was not in a block."
+ (when (and (funcall hs-find-block-beginning-func)
+ (funcall hs-looking-at-block-start-p-func))
+ ;; point is inside a block
+ (goto-char (match-end 0))))
+
(defun hs-overlay-at (position)
"Return hideshow overlay at POSITION, or nil if none to be found."
(let ((overlays (overlays-at position))
@@ -802,12 +808,13 @@ and `case-fold-search' are both t."
(if (and c-reg (nth 0 c-reg))
;; point is inside a comment, and that comment is hideable
(goto-char (nth 0 c-reg))
- (end-of-line)
- (when (and (not c-reg)
- (funcall hs-find-block-beginning-func)
- (funcall hs-looking-at-block-start-p-func))
- ;; point is inside a block
- (goto-char (match-end 0)))))
+ (when (not c-reg)
+ (end-of-line)
+ (when (not (hs-find-block-beginning-match))
+ ;; We should also consider ourselves "in" a hidden block when
+ ;; point is right at the edge after a hidden block (bug#52092).
+ (beginning-of-line)
+ (hs-find-block-beginning-match)))))
(end-of-line)
(hs-overlay-at (point))))
@@ -948,9 +955,9 @@ The hook `hs-hide-hook' is run; see `run-hooks'."
"Toggle hiding/showing of a block.
See `hs-hide-block' and `hs-show-block'.
Argument E should be the event that triggered this action."
- (interactive)
+ (interactive (list last-nonmenu-event))
(hs-life-goes-on
- (posn-set-point (event-end e))
+ (when e (posn-set-point (event-end e)))
(if (hs-already-hidden-p)
(hs-show-block)
(hs-hide-block))))
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el
index cbbcf1c2b7c..5f265212992 100644
--- a/lisp/progmodes/make-mode.el
+++ b/lisp/progmodes/make-mode.el
@@ -488,17 +488,12 @@ not be enclosed in { } or ( )."
(defconst makefile-imake-font-lock-keywords
- (append
- (makefile-make-font-lock-keywords
- makefile-var-use-regex
- makefile-statements
- t
- nil
- '("^XCOMM.*$" . font-lock-comment-face)
- '("XVAR\\(?:use\\|def\\)[0-9]" 0 font-lock-keyword-face prepend)
- '("@@" . font-lock-preprocessor-face)
- )
- cpp-font-lock-keywords))
+ (append (list '("XCOMM.*$" . font-lock-comment-face)
+ '("XVAR\\(?:use\\|def\\)[0-9]" 0
+ font-lock-keyword-face prepend)
+ '("@@" . font-lock-preprocessor-face))
+ cpp-font-lock-keywords
+ makefile-font-lock-keywords))
(defconst makefile-syntax-propertize-function
@@ -932,7 +927,9 @@ Makefile mode can be configured by modifying the following variables:
:syntax-table makefile-imake-mode-syntax-table
(setq-local syntax-propertize-function nil)
(setq font-lock-defaults
- `(makefile-imake-font-lock-keywords ,@(cdr font-lock-defaults))))
+ `(makefile-imake-font-lock-keywords ,@(cdr font-lock-defaults)))
+ (setq-local comment-start "XCOMM")
+ (setq-local comment-start-skip "XCOMM[ \t]*"))
diff --git a/lisp/progmodes/opascal.el b/lisp/progmodes/opascal.el
index 5ed719b5a78..fb1e501066d 100644
--- a/lisp/progmodes/opascal.el
+++ b/lisp/progmodes/opascal.el
@@ -275,8 +275,7 @@ nested routine.")
(declare (debug t))
`(save-excursion
(save-match-data
- (let ((inhibit-point-motion-hooks t)
- (deactivate-mark nil))
+ (let ((deactivate-mark nil))
(progn ,@forms)))))
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index 70cb4605683..7b7a2cdf019 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -242,6 +242,12 @@
(not (nth 3 (syntax-ppss
(match-beginning 0))))))
(string-to-syntax ". p"))))
+ ;; If "\" is acting as a backslash operator, it shouldn't start an
+ ;; escape sequence, so change its syntax. This allows us to handle
+ ;; correctly the \() construct (Bug#11996) as well as references
+ ;; to string values.
+ ("\\(\\\\\\)['`\"($]" (1 (unless (nth 3 (syntax-ppss))
+ (string-to-syntax "."))))
;; Handle funny names like $DB'stop.
("\\$ ?{?\\^?[_[:alpha:]][_[:alnum:]]*\\('\\)[_[:alpha:]]" (1 "_"))
;; format statements
@@ -280,6 +286,7 @@
(backward-sexp 1)
(member (buffer-substring (point) end)
perl--syntax-exp-intro-keywords)))
+ (bobp)
(memq (char-before)
'(?? ?: ?. ?, ?\; ?= ?! ?~ ?\( ?\[))))))
nil ;; A division sign instead of a regexp-match.
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
index 7738de6a745..f87230bd2f5 100644
--- a/lisp/progmodes/prog-mode.el
+++ b/lisp/progmodes/prog-mode.el
@@ -100,11 +100,9 @@
menu)
-(defvar prog-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [?\C-\M-q] 'prog-indent-sexp)
- map)
- "Keymap used for programming modes.")
+(defvar-keymap prog-mode-map
+ :doc "Keymap used for programming modes."
+ "C-M-q" #'prog-indent-sexp)
(defvar prog-indentation-context nil
"When non-nil, provides context for indenting embedded code chunks.
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index ee94d0d85d8..ac278edd409 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1,7 +1,7 @@
;;; project.el --- Operations on the current project -*- lexical-binding: t; -*-
;; Copyright (C) 2015-2022 Free Software Foundation, Inc.
-;; Version: 0.8.1
+;; Version: 0.8.2
;; Package-Requires: ((emacs "26.1") (xref "1.4.0"))
;; This is a GNU ELPA :core package. Avoid using functionality that
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 9f9439aac69..0de76b0bde3 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -300,6 +300,7 @@ instead."
(define-key map [remap backward-sentence] #'python-nav-backward-block)
(define-key map [remap forward-sentence] #'python-nav-forward-block)
(define-key map [remap backward-up-list] #'python-nav-backward-up-list)
+ (define-key map [remap up-list] #'python-nav-up-list)
(define-key map [remap mark-defun] #'python-mark-defun)
(define-key map "\C-c\C-j" #'imenu)
;; Indent specific
@@ -3086,8 +3087,8 @@ interpreter is run. Variables
`python-shell-font-lock-enable',
`python-shell-completion-setup-code',
`python-shell-completion-string-code',
-`python-eldoc-setup-code', `python-eldoc-string-code',
-`python-ffap-setup-code' and `python-ffap-string-code' can
+`python-eldoc-setup-code',
+`python-ffap-setup-code' can
customize this mode for different Python interpreters.
This mode resets `comint-output-filter-functions' locally, so you
@@ -3217,6 +3218,26 @@ process buffer for a list of commands.)"
show)))
(get-buffer-process buffer)))
+(defun python-shell-restart (&optional show)
+ "Restart the Python shell.
+Optional argument SHOW (interactively, the prefix argument), if
+non-nil, means also display the Python shell buffer."
+ (interactive "P")
+ (with-current-buffer
+ (or (and (derived-mode-p 'inferior-python-mode)
+ (current-buffer))
+ (seq-some (lambda (dedicated)
+ (get-buffer (format "*%s*" (python-shell-get-process-name
+ dedicated))))
+ '(buffer project nil))
+ (user-error "No Python shell"))
+ (when-let ((proc (get-buffer-process (current-buffer))))
+ (kill-process proc)
+ (while (accept-process-output proc)))
+ (python-shell-make-comint (python-shell-calculate-command)
+ (string-trim (buffer-name) "\\*" "\\*")
+ show)))
+
(defun run-python-internal ()
"Run an inferior Internal Python process.
Input and output via buffer named after
@@ -3392,15 +3413,25 @@ detecting a prompt at the end of the buffer."
"Send STRING to PROCESS and inhibit output.
Return the output."
(or process (setq process (python-shell-get-process-or-error)))
- (cl-letf (((process-filter process)
- (lambda (_proc str)
- (with-current-buffer (process-buffer process)
- (python-shell-output-filter str))))
- (python-shell-output-filter-in-progress t)
- (inhibit-quit t))
+ (cl-letf* (((process-filter process)
+ (lambda (_proc str)
+ (with-current-buffer (process-buffer process)
+ (python-shell-output-filter str))))
+ (python-shell-output-filter-in-progress t)
+ (inhibit-quit t)
+ (buffer (process-buffer process))
+ (last-prompt (cond ((boundp 'comint-last-prompt-overlay)
+ 'comint-last-prompt-overlay)
+ ((boundp 'comint-last-prompt)
+ 'comint-last-prompt)))
+ (last-prompt-value (buffer-local-value last-prompt buffer)))
(or
(with-local-quit
- (python-shell-send-string string process)
+ (unwind-protect
+ (python-shell-send-string string process)
+ (when (not (null last-prompt))
+ (with-current-buffer buffer
+ (set last-prompt last-prompt-value))))
(while python-shell-output-filter-in-progress
;; `python-shell-output-filter' takes care of setting
;; `python-shell-output-filter-in-progress' to NIL after it
@@ -3409,7 +3440,7 @@ Return the output."
(prog1
python-shell-output-filter-buffer
(setq python-shell-output-filter-buffer nil)))
- (with-current-buffer (process-buffer process)
+ (with-current-buffer buffer
(comint-interrupt-subjob)))))
(defun python-shell-internal-send-string (string)
@@ -4038,7 +4069,8 @@ With argument MSG show activation/deactivation message."
Optional argument PROCESS forces completions to be retrieved
using that one instead of current buffer's process."
(setq process (or process (get-buffer-process (current-buffer))))
- (let* ((line-start (if (derived-mode-p 'inferior-python-mode)
+ (let* ((is-shell-buffer (derived-mode-p 'inferior-python-mode))
+ (line-start (if is-shell-buffer
;; Working on a shell buffer: use prompt end.
(cdr (python-util-comint-last-prompt))
(line-beginning-position)))
@@ -4069,7 +4101,8 @@ using that one instead of current buffer's process."
(completion-fn
(with-current-buffer (process-buffer process)
(cond ((or (null prompt)
- (< (point) (cdr prompt-boundaries)))
+ (and is-shell-buffer
+ (< (point) (cdr prompt-boundaries))))
#'ignore)
((or (not python-shell-completion-native-enable)
;; Even if native completion is enabled, for
@@ -5484,11 +5517,11 @@ operator."
"Check if point is at `beginning-of-defun' using SYNTAX-PPSS.
When CHECK-STATEMENT is non-nil, the current statement is checked
instead of the current physical line."
- (and (not (python-syntax-context-type (or syntax-ppss (syntax-ppss))))
- (save-excursion
- (when check-statement
- (python-nav-beginning-of-statement))
- (beginning-of-line 1)
+ (save-excursion
+ (when check-statement
+ (python-nav-beginning-of-statement))
+ (beginning-of-line 1)
+ (and (not (python-syntax-context-type (or syntax-ppss (syntax-ppss))))
(looking-at python-nav-beginning-of-defun-regexp))))
(defun python-info-looking-at-beginning-of-block ()
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 517fbbd8e7b..558b62b20ae 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -31,6 +31,9 @@
;; available for filenames, variables known from the script, the shell and
;; the environment as well as commands.
+;; A Flymake backend using the "shellcheck" program is provided. See
+;; https://www.shellcheck.net/ for installation instructions.
+
;;; Known Bugs:
;; - In Bourne the keyword `in' is not anchored to case, for, select ...
@@ -141,7 +144,9 @@
(eval-when-compile
(require 'skeleton)
(require 'cl-lib)
- (require 'comint))
+ (require 'comint)
+ (require 'let-alist)
+ (require 'subr-x))
(require 'executable)
(autoload 'comint-completion-at-point "comint")
@@ -1580,6 +1585,7 @@ with your script for an edit-interpret-debug cycle."
((equal (file-name-nondirectory buffer-file-name) ".profile") "sh")
(t sh-shell-file))
nil nil)
+ (add-hook 'flymake-diagnostic-functions #'sh-shellcheck-flymake nil t)
(add-hook 'hack-local-variables-hook
#'sh-after-hack-local-variables nil t))
@@ -3103,6 +3109,88 @@ shell command and conveniently use this command."
(delete-region (1+ (point))
(progn (skip-chars-backward " \t") (point)))))))
+;;; Flymake backend
+
+(defcustom sh-shellcheck-program "shellcheck"
+ "Name of the shellcheck executable."
+ :type 'string
+ :version "29.1")
+
+(defcustom sh-shellcheck-arguments nil
+ "Additional arguments to the shellcheck program."
+ :type '(repeat string)
+ :version "29.1")
+
+(defvar-local sh--shellcheck-process nil)
+
+(defalias 'sh--json-read
+ (if (fboundp 'json-parse-buffer)
+ (lambda () (json-parse-buffer :object-type 'alist))
+ (require 'json)
+ 'json-read))
+
+(defun sh-shellcheck-flymake (report-fn &rest _args)
+ "Flymake backend using the shellcheck program.
+Takes a Flymake callback REPORT-FN as argument, as expected of a
+member of `flymake-diagnostic-functions'."
+ (when (process-live-p sh--shellcheck-process)
+ (kill-process sh--shellcheck-process))
+ (let* ((source (current-buffer))
+ (dialect (named-let recur ((s sh-shell))
+ (pcase s
+ ((or 'bash 'dash 'sh) (symbol-name s))
+ ('ksh88 "ksh")
+ ((guard s)
+ (recur (alist-get s sh-ancestor-alist))))))
+ (sentinel
+ (lambda (proc _event)
+ (when (memq (process-status proc) '(exit signal))
+ (unwind-protect
+ (if (with-current-buffer source
+ (not (eq proc sh--shellcheck-process)))
+ (flymake-log :warning "Canceling obsolete check %s" proc)
+ (with-current-buffer (process-buffer proc)
+ (goto-char (point-min))
+ (thread-last
+ (sh--json-read)
+ (alist-get 'comments)
+ (seq-filter
+ (lambda (item)
+ (let-alist item (string= .file "-"))))
+ (mapcar
+ (lambda (item)
+ (let-alist item
+ (flymake-make-diagnostic
+ source
+ (cons .line .column)
+ (unless (and (eq .line .endLine)
+ (eq .column .endColumn))
+ (cons .endLine .endColumn))
+ (pcase .level
+ ("error" :error)
+ ("warning" :warning)
+ (_ :note))
+ (format "SC%s: %s" .code .message)))))
+ (funcall report-fn))))
+ (kill-buffer (process-buffer proc)))))))
+ (unless dialect
+ (error "`sh-shellcheck-flymake' is not suitable for shell type `%s'"
+ sh-shell))
+ (setq sh--shellcheck-process
+ (make-process
+ :name "shellcheck" :noquery t :connection-type 'pipe
+ :buffer (generate-new-buffer " *flymake-shellcheck*")
+ :command `(,sh-shellcheck-program
+ "--format=json1"
+ "-s" ,dialect
+ ,@sh-shellcheck-arguments
+ "-")
+ :sentinel sentinel))
+ (save-restriction
+ (widen)
+ (process-send-region sh--shellcheck-process (point-min) (point-max))
+ (process-send-eof sh--shellcheck-process))))
+
(provide 'sh-script)
;;; sh-script.el ends here
diff --git a/lisp/progmodes/subword.el b/lisp/progmodes/subword.el
index e06eb9a6f70..34327f756ee 100644
--- a/lisp/progmodes/subword.el
+++ b/lisp/progmodes/subword.el
@@ -79,12 +79,11 @@
"\\(\\(\\W\\|[[:lower:][:digit:]]\\)\\([[:upper:]]+\\W*\\)\\|\\W\\w+\\)"
"Regexp used by `subword-backward-internal'.")
-(defvar subword-mode-map
+(defvar-keymap subword-mode-map
;; We originally remapped motion keys here, but now use Emacs core
;; hooks. Leave this keymap around so that user additions to it
;; keep working.
- (make-sparse-keymap)
- "Keymap used in `subword-mode' minor mode.")
+ :doc "Keymap used in `subword-mode' minor mode.")
;;;###autoload
(define-obsolete-function-alias
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index fa799a0fb37..d6b8edaa365 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -3409,7 +3409,8 @@ A change is considered significant if it affects the buffer text
in any way that isn't completely restored again. Any
user-visible changes to the buffer must not be within a
`verilog-save-buffer-state'."
- `(let ((inhibit-point-motion-hooks t)
+ `(let (,@(unless (>= emacs-major-version 25)
+ '((inhibit-point-motion-hooks t)))
(verilog-no-change-functions t))
,(if (fboundp 'with-silent-modifications)
`(with-silent-modifications ,@body)
@@ -3455,11 +3456,13 @@ For insignificant changes, see instead `verilog-save-buffer-state'."
(run-hook-with-args 'before-change-functions (point-min) (point-max))
(unwind-protect
;; Must inhibit and restore hooks before restoring font-lock
- (let* ((inhibit-point-motion-hooks t)
+ (let* (,@(unless (>= emacs-major-version 25)
+ '((inhibit-point-motion-hooks t) ;Obsolete since 25.1
+ ;; XEmacs and pre-Emacs 21 ignore
+ ;; `inhibit-modification-hooks'.
+ before-change-functions after-change-functions))
(inhibit-modification-hooks t)
- (verilog-no-change-functions t)
- ;; XEmacs and pre-Emacs 21 ignore inhibit-modification-hooks.
- before-change-functions after-change-functions)
+ (verilog-no-change-functions t))
(progn ,@body))
;; Unwind forms
(run-hook-with-args 'after-change-functions (point-min) (point-max)
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index b763da3fbc5..a36bb7fbe44 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -2507,11 +2507,10 @@ consistent searching."
(defmacro vhdl-prepare-search-2 (&rest body)
"Enable case insensitive search, switch to syntax table that includes `_',
-arrange to ignore `intangible' overlays, then execute BODY, and finally restore
-the old environment. Used for consistent searching."
+then execute BODY, and finally restore the old environment.
+Used for consistent searching."
(declare (debug t))
- `(let ((case-fold-search t) ; case insensitive search
- (inhibit-point-motion-hooks t))
+ `(let ((case-fold-search t)) ; case insensitive search
;; use extended syntax table
(with-syntax-table vhdl-mode-ext-syntax-table
;; execute BODY safely
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index ac04b64ce59..bb36688ef85 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -751,17 +751,22 @@ quit the *xref* buffer."
(defun xref-query-replace-in-results (from to)
"Perform interactive replacement of FROM with TO in all displayed xrefs.
-This command interactively replaces FROM with TO in the names of the
+This function interactively replaces FROM with TO in the names of the
references displayed in the current *xref* buffer.
-When called interactively, it uses '.*' as FROM, which means
-replace the whole name. Unless called with prefix argument, in
-which case the user is prompted for both FROM and TO.
+When called interactively, it uses '.*' as FROM, which means replace
+the whole name, and prompts the user for TO.
+If invoked with prefix argument, it prompts the user for both FROM and TO.
As each match is found, the user must type a character saying
what to do with it. Type SPC or `y' to replace the match,
DEL or `n' to skip and go to the next match. For more directions,
-type \\[help-command] at that time."
+type \\[help-command] at that time.
+
+Note that this function cannot be used in *xref* buffers that show
+a partial list of all references, such as the *xref* buffer created
+by \\[xref-find-definitions] and its variants, since those list only
+some of the references to the identifiers."
(interactive
(let* ((fr
(if current-prefix-arg
@@ -891,7 +896,9 @@ ITEMS is an xref item which " ; FIXME: Expand documentation.
(setq pairs (cdr buf-pairs))
(setq continue
(perform-replace from to t t nil nil multi-query-replace-map)))
- (unless did-it-once (user-error "No suitable matches here"))
+ (unless did-it-once
+ (user-error
+ "Cannot perform global renaming of symbols using find-definition results"))
(when (and continue (not buf-pairs))
(message "All results processed"))))
diff --git a/lisp/repeat.el b/lisp/repeat.el
index a32f3a4c507..0ae68d6024d 100644
--- a/lisp/repeat.el
+++ b/lisp/repeat.el
@@ -89,9 +89,15 @@
;;;;; ************************* USER OPTIONS ************************** ;;;;;
+(defgroup repeat nil
+ "Convenient way to repeat previous commands."
+ :prefix "repeat-"
+ :version "29.1"
+ :group 'convenience)
+
(defcustom repeat-too-dangerous '(kill-this-buffer)
"Commands too dangerous to repeat with \\[repeat]."
- :group 'convenience
+ :group 'repeat
:type '(repeat function))
;; If the last command was self-insert-command, the char to be inserted was
@@ -120,7 +126,7 @@ if `repeat' is bound to C-x z, typing C-x z z z repeats the previous command
3 times. If this variable is a sequence of characters, then re-execution
only occurs if the final character by which `repeat' was invoked is a
member of that sequence. If this variable is nil, no re-execution occurs."
- :group 'convenience
+ :group 'repeat
:type '(choice (const :tag "Repeat for all keys" t)
(const :tag "Don't repeat" nil)
(sexp :tag "Repeat for specific keys")))
@@ -338,8 +344,8 @@ recently executed command not bound to an input event\"."
"Key that stops the modal repeating of keys in sequence.
For example, you can set it to <return> like `isearch-exit'."
:type '(choice (const :tag "No special key to exit repeating sequence" nil)
- (key-sequence :tag "Key that exits repeating sequence"))
- :group 'convenience
+ (key :tag "Kbd keys that exit repeating sequence"))
+ :group 'repeat
:version "28.1")
(defcustom repeat-exit-timeout nil
@@ -350,16 +356,19 @@ You can also set the property `repeat-exit-timeout' on the command symbol.
This property can override the value of this variable."
:type '(choice (const :tag "No timeout to exit repeating sequence" nil)
(number :tag "Timeout in seconds to exit repeating"))
- :group 'convenience
+ :group 'repeat
:version "28.1")
+(defvar repeat-exit-function nil
+ "Function that exits the repeating sequence.")
+
(defvar repeat-exit-timer nil
"Timer activated after the last key typed in the repeating key sequence.")
(defcustom repeat-keep-prefix nil
"Whether to keep the prefix arg of the previous command when repeating."
:type 'boolean
- :group 'convenience
+ :group 'repeat
:version "28.1")
(defcustom repeat-check-key t
@@ -377,7 +386,7 @@ When the variable value is non-nil, but the property value is `no',
then don't check the last key. Also when the variable value is nil,
but the property value is `t', then check the last key."
:type 'boolean
- :group 'convenience
+ :group 'repeat
:version "28.1")
(defcustom repeat-echo-function #'repeat-echo-message
@@ -390,7 +399,7 @@ a repeating map, or nil after deactivating the transient repeating mode."
repeat-echo-mode-line)
(const :tag "No visual feedback" ignore)
(function :tag "Function"))
- :group 'convenience
+ :group 'repeat
:version "28.1")
(defvar repeat-in-progress nil
@@ -408,7 +417,7 @@ the map can't be set on the command symbol property `repeat-map'.")
When Repeat mode is enabled, and the command symbol has the property named
`repeat-map', this map is activated temporarily for the next command.
See `describe-repeat-maps' for a list of all repeatable commands."
- :global t :group 'convenience
+ :global t :group 'repeat
(if (not repeat-mode)
(remove-hook 'post-command-hook 'repeat-post-hook)
(add-hook 'post-command-hook 'repeat-post-hook)
@@ -466,36 +475,47 @@ See `describe-repeat-maps' for a list of all repeatable commands."
;; Adding an exit key
(when repeat-exit-key
- (define-key map repeat-exit-key 'ignore))
+ (define-key map (if (key-valid-p repeat-exit-key)
+ (kbd repeat-exit-key)
+ repeat-exit-key)
+ 'ignore))
(when (and repeat-keep-prefix (not prefix-arg))
(setq prefix-arg current-prefix-arg))
(setq repeat-in-progress t)
(let ((exitfun (set-transient-map map)))
-
- (when repeat-exit-timer
- (cancel-timer repeat-exit-timer)
- (setq repeat-exit-timer nil))
+ (repeat--exit)
+ (setq repeat-exit-function exitfun)
(let* ((prop (repeat--command-property 'repeat-exit-timeout))
(timeout (unless (eq prop 'no) (or prop repeat-exit-timeout))))
(when timeout
(setq repeat-exit-timer
- (run-with-idle-timer
- timeout nil
- (lambda ()
- (setq repeat-in-progress nil)
- (funcall exitfun)
- (funcall repeat-echo-function nil))))))))))))
+ (run-with-idle-timer timeout nil #'repeat-exit))))))))))
(setq repeat-map nil)
(setq repeat--prev-mb (cons (minibuffer-depth) current-minibuffer-command))
(when (and was-in-progress (not repeat-in-progress))
- (when repeat-exit-timer
- (cancel-timer repeat-exit-timer)
- (setq repeat-exit-timer nil))
- (funcall repeat-echo-function nil))))
+ (repeat-exit))))
+
+;;;###autoload
+(defun repeat-exit ()
+ "Exit the repeating sequence.
+This function can be used to force exit of repetition while it's active."
+ (interactive)
+ (setq repeat-in-progress nil)
+ (repeat--exit)
+ (funcall repeat-echo-function nil))
+
+(defun repeat--exit ()
+ "Internal function to clean up previously set exit function and timer."
+ (when repeat-exit-timer
+ (cancel-timer repeat-exit-timer)
+ (setq repeat-exit-timer nil))
+ (when repeat-exit-function
+ (funcall repeat-exit-function)
+ (setq repeat-exit-function nil)))
(defun repeat-echo-message-string (keymap)
"Return a string with a list of repeating keys."
@@ -510,7 +530,9 @@ See `describe-repeat-maps' for a list of all repeatable commands."
(if repeat-exit-key
(substitute-command-keys
(format ", or exit with \\`%s'"
- (key-description repeat-exit-key)))
+ (if (key-valid-p repeat-exit-key)
+ repeat-exit-key
+ (key-description repeat-exit-key))))
""))))
(defun repeat-echo-message (keymap)
diff --git a/lisp/replace.el b/lisp/replace.el
index 6393c092886..8f81ec33a6e 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -2817,8 +2817,8 @@ which will run faster and probably do exactly what you want. Please
see the documentation of `replace-match' to find out how to simulate
`case-replace'.
-This function returns nil if and only if there were no matches to
-make, or the user didn't cancel the call.
+This function returns nil if there were no matches to make, or
+the user cancelled the call.
REPLACEMENTS is either a string, a list of strings, or a cons cell
containing a function and its first argument. The function is
diff --git a/lisp/reveal.el b/lisp/reveal.el
index 64e9ceef644..b3b42177f94 100644
--- a/lisp/reveal.el
+++ b/lisp/reveal.el
@@ -210,13 +210,11 @@ that text."
(let ((reveal-auto-hide t))
(reveal-post-command)))
-(defvar reveal-mode-map
- (let ((map (make-sparse-keymap)))
- ;; Override the default move-beginning-of-line and move-end-of-line
- ;; which skips valuable invisible text.
- (define-key map [remap move-beginning-of-line] 'beginning-of-line)
- (define-key map [remap move-end-of-line] 'end-of-line)
- map))
+(defvar-keymap reveal-mode-map
+ ;; Override the default move-beginning-of-line and move-end-of-line
+ ;; which skips valuable invisible text.
+ "<remap> <move-beginning-of-line>" #'beginning-of-line
+ "<remap> <move-end-of-line>" #'end-of-line)
;;;###autoload
(define-minor-mode reveal-mode
diff --git a/lisp/server.el b/lisp/server.el
index 3caa335c4eb..90d97c1538e 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1589,14 +1589,19 @@ specifically for the clients and did not exist before their request for it."
(server-buffer-done (current-buffer))))
(defun server-kill-emacs-query-function ()
- "Ask before exiting Emacs if it has live clients.
+ "Ask before exiting Emacs if it has other live clients.
A \"live client\" is a client with at least one live buffer
-associated with it."
- (or (not (seq-some (lambda (proc)
- (seq-some #'buffer-live-p
- (process-get proc 'buffers)))
- server-clients))
- (yes-or-no-p "This Emacs session has clients; exit anyway? ")))
+associated with it. These clients were (probably) started by
+external processes that are waiting for some buffers to be
+edited. If there are any other clients, we don't want to fail
+their waiting processes, so ask the user to be sure."
+ (let ((this-client (frame-parameter nil 'client)))
+ (or (not (seq-some (lambda (proc)
+ (unless (eq proc this-client)
+ (seq-some #'buffer-live-p
+ (process-get proc 'buffers))))
+ server-clients))
+ (yes-or-no-p "This Emacs session has other clients; exit anyway? "))))
(defun server-kill-buffer ()
"Remove the current buffer from its clients' buffer list.
diff --git a/lisp/shell.el b/lisp/shell.el
index 87fd36a5929..641f274045d 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -308,10 +308,11 @@ for Shell mode only."
(const :tag "on" t))
:group 'shell)
-(defcustom shell-comint-fl-enable t
+(defcustom shell-fontify-input-enable t
"Enable fontification of input in shell buffers.
This variable only has effect when the shell is started. Use the
-command `comint-fl-mode' to toggle fontification of input."
+command `comint-fontify-input-mode' to toggle fontification of
+input."
:type 'boolean
:group 'shell
:safe 'booleanp
@@ -324,7 +325,7 @@ enabled, is performed in an indirect buffer, whose indentation
and syntax highlighting is set up with `sh-mode'. In addition to
`comint-indirect-setup-hook', run this hook with the indirect
buffer as the current buffer after its setup is done. This can
-be used to further customize fontification and other behaviour of
+be used to further customize fontification and other behavior of
the indirect buffer."
:type 'boolean
:group 'shell
@@ -623,8 +624,8 @@ command."
:interactive nil
:after-hook
(unless comint-use-prompt-regexp
- (if shell-comint-fl-enable
- (comint-fl-mode))
+ (if shell-fontify-input-enable
+ (comint-fontify-input-mode))
(if shell-highlight-undef-enable
(shell-highlight-undef-mode)))
@@ -1664,8 +1665,8 @@ Similar to `executable-find', but use cache stored in
(if buf (buffer-local-value 'default-directory buf)
default-directory)))
(cond
- ;; Don't highlight command output. Mostly useful if
- ;; `comint-fl-mode' is disabled.
+ ;; Don't fontify command output. Mostly useful if
+ ;; `comint-fontify-input-mode' is disabled.
((text-property-any beg (point) 'field 'output)
nil)
((member cmd shell-highlight-undef-aliases)
@@ -1696,7 +1697,7 @@ Similar to `executable-find', but use cache stored in
(define-minor-mode shell-highlight-undef-mode
"Highlight undefined shell commands and aliases.
This minor mode is mostly useful in `shell-mode' buffers and
-works better if `comint-fl-mode' is enabled."
+works better if `comint-fontify-input-mode' is enabled."
:init-value nil
(if shell--highlight-undef-indirect
(progn
@@ -1706,7 +1707,7 @@ works better if `comint-fl-mode' is enabled."
(with-current-buffer buf
(font-lock-remove-keywords nil shell-highlight-undef-keywords))))
(font-lock-remove-keywords nil shell-highlight-undef-keywords))
- (remove-hook 'comint-fl-mode-hook
+ (remove-hook 'comint-fontify-input-mode-hook
#'shell-highlight-undef-mode-restart t)
(when shell-highlight-undef-mode
@@ -1722,9 +1723,9 @@ works better if `comint-fl-mode' is enabled."
(concat
"\\("
"[;(){}`|&]"
- (if comint-fl-mode
- ;; `comint-fl-mode' already puts point-min on end of
- ;; prompt
+ (if comint-fontify-input-mode
+ ;; `comint-fontify-input-mode' already puts
+ ;; point-min on end of prompt
""
(concat "\\|" comint-prompt-regexp))
"\\|^"
@@ -1740,7 +1741,7 @@ works better if `comint-fl-mode' is enabled."
(lambda ()
(setq shell-highlight-undef-regexp regexp)
(font-lock-add-keywords nil shell-highlight-undef-keywords t))))
- (cond (comint-fl-mode
+ (cond (comint-fontify-input-mode
(setq shell--highlight-undef-indirect setup)
(if-let ((buf (comint-indirect-buffer t)))
(with-current-buffer buf
@@ -1748,7 +1749,7 @@ works better if `comint-fl-mode' is enabled."
(add-hook 'comint-indirect-setup-hook setup nil t)))
(t (funcall setup))))
- (add-hook 'comint-fl-mode-hook
+ (add-hook 'comint-fontify-input-mode-hook
#'shell-highlight-undef-mode-restart nil t))
(font-lock-flush))
@@ -1756,9 +1757,9 @@ works better if `comint-fl-mode' is enabled."
(defun shell-highlight-undef-mode-restart ()
"If `shell-highlight-undef-mode' is on, restart it.
`shell-highlight-undef-mode' performs its setup differently
-depending on `comint-fl-mode'. It's useful to call this function
-when switching `comint-fl-mode' in order to make
-`shell-highlight-undef-mode' redo its setup."
+depending on `comint-fontify-input-mode'. It's useful to call
+this function when switching `comint-fontify-input-mode' in order
+to make `shell-highlight-undef-mode' redo its setup."
(when shell-highlight-undef-mode
(shell-highlight-undef-mode 1)))
diff --git a/lisp/simple.el b/lisp/simple.el
index 60f2ad34528..e804f717b01 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2465,9 +2465,13 @@ Also see `suggest-key-bindings'."
(defun execute-extended-command--shorter (name typed)
(let ((candidates '())
+ commands
(max (length typed))
(len 1)
binding)
+ ;; Precompute a list of commands once to avoid repeated `commandp' testing
+ ;; of symbols in the `completion-try-completion' call inside the loop below
+ (mapatoms (lambda (s) (when (commandp s) (push s commands))))
(while (and (not binding)
(progn
(unless candidates
@@ -2480,8 +2484,8 @@ Also see `suggest-key-bindings'."
(input-pending-p) ;Dummy call to trigger input-processing, bug#23002.
(let ((candidate (pop candidates)))
(when (equal name
- (car-safe (completion-try-completion
- candidate obarray 'commandp len)))
+ (car-safe (completion-try-completion
+ candidate commands nil len)))
(setq binding candidate))))
binding))
@@ -2653,6 +2657,9 @@ function as needed."
(cl-defmethod function-documentation ((function accessor))
(oclosure--accessor-docstring function)) ;; FIXME: η-reduce!
+(cl-defmethod function-documentation ((f cconv--interactive-helper))
+ (function-documentation (cconv--interactive-helper--fun f)))
+
;; This should be in `oclosure.el' but that file is loaded before `cl-generic'.
(cl-defgeneric oclosure-interactive-form (_function)
"Return the interactive form of FUNCTION or nil if none.
@@ -2664,6 +2671,9 @@ instead."
;; (interactive-form function)
nil)
+(cl-defmethod oclosure-interactive-form ((f cconv--interactive-helper))
+ `(interactive (funcall ',(cconv--interactive-helper--if f))))
+
(defun command-execute (cmd &optional record-flag keys special)
;; BEWARE: Called directly from the C code.
"Execute CMD as an editor command.
@@ -3520,8 +3530,6 @@ Return what remains of the list."
;; In a writable buffer, enable undoing read-only text that is
;; so because of text properties.
(inhibit-read-only t)
- ;; Don't let `intangible' properties interfere with undo.
- (inhibit-point-motion-hooks t)
;; We use oldlist only to check for EQ. ++kfs
(oldlist buffer-undo-list)
(did-apply nil)
@@ -4563,85 +4571,81 @@ impose the use of a shell (with its need to quote arguments)."
(set-marker (mark-marker) (point)
(current-buffer)))))
;; Output goes in a separate buffer.
- ;; Preserve the match data in case called from a program.
- ;; FIXME: It'd be ridiculous for an Elisp function to call
- ;; shell-command and assume that it won't mess the match-data!
- (save-match-data
- (if (string-match "[ \t]*&[ \t]*\\'" command)
- ;; Command ending with ampersand means asynchronous.
- (let* ((buffer (get-buffer-create
- (or output-buffer shell-command-buffer-name-async)))
- (bname (buffer-name buffer))
- (proc (get-buffer-process buffer))
- (directory default-directory))
- ;; Remove the ampersand.
- (setq command (substring command 0 (match-beginning 0)))
- ;; Ask the user what to do with already running process.
- (when proc
- (cond
- ((eq async-shell-command-buffer 'confirm-kill-process)
- ;; If will kill a process, query first.
- (shell-command--same-buffer-confirm "Kill it")
- (kill-process proc))
- ((eq async-shell-command-buffer 'confirm-new-buffer)
- ;; If will create a new buffer, query first.
- (shell-command--same-buffer-confirm "Use a new buffer")
- (setq buffer (generate-new-buffer bname)))
- ((eq async-shell-command-buffer 'new-buffer)
- ;; It will create a new buffer.
- (setq buffer (generate-new-buffer bname)))
- ((eq async-shell-command-buffer 'confirm-rename-buffer)
- ;; If will rename the buffer, query first.
- (shell-command--same-buffer-confirm "Rename it")
- (with-current-buffer buffer
- (rename-uniquely))
- (setq buffer (get-buffer-create bname)))
- ((eq async-shell-command-buffer 'rename-buffer)
- ;; It will rename the buffer.
- (with-current-buffer buffer
- (rename-uniquely))
- (setq buffer (get-buffer-create bname)))))
- (with-current-buffer buffer
- (shell-command-save-pos-or-erase)
- (setq default-directory directory)
- (require 'shell)
- (let ((process-environment
- (append
- (and (natnump async-shell-command-width)
- (list
- (format "COLUMNS=%d"
- async-shell-command-width)))
- (comint-term-environment)
- process-environment)))
- (setq proc
- (start-process-shell-command "Shell" buffer command)))
- (setq mode-line-process '(":%s"))
- (shell-mode)
- (setq-local revert-buffer-function
- (lambda (&rest _)
- (async-shell-command command buffer)))
- (set-process-sentinel proc #'shell-command-sentinel)
- ;; Use the comint filter for proper handling of
- ;; carriage motion (see comint-inhibit-carriage-motion).
- (set-process-filter proc #'comint-output-filter)
- (if async-shell-command-display-buffer
- ;; Display buffer immediately.
- (display-buffer buffer '(nil (allow-no-window . t)))
- ;; Defer displaying buffer until first process output.
- ;; Use disposable named advice so that the buffer is
- ;; displayed at most once per process lifetime.
- (let ((nonce (make-symbol "nonce")))
- (add-function :before (process-filter proc)
- (lambda (proc _string)
- (let ((buf (process-buffer proc)))
- (when (buffer-live-p buf)
- (remove-function (process-filter proc)
- nonce)
- (display-buffer buf))))
- `((name . ,nonce)))))))
- ;; Otherwise, command is executed synchronously.
- (shell-command-on-region (point) (point) command
- output-buffer nil error-buffer)))))))
+ (if (string-match "[ \t]*&[ \t]*\\'" command)
+ ;; Command ending with ampersand means asynchronous.
+ (let* ((buffer (get-buffer-create
+ (or output-buffer shell-command-buffer-name-async)))
+ (bname (buffer-name buffer))
+ (proc (get-buffer-process buffer))
+ (directory default-directory))
+ ;; Remove the ampersand.
+ (setq command (substring command 0 (match-beginning 0)))
+ ;; Ask the user what to do with already running process.
+ (when proc
+ (cond
+ ((eq async-shell-command-buffer 'confirm-kill-process)
+ ;; If will kill a process, query first.
+ (shell-command--same-buffer-confirm "Kill it")
+ (kill-process proc))
+ ((eq async-shell-command-buffer 'confirm-new-buffer)
+ ;; If will create a new buffer, query first.
+ (shell-command--same-buffer-confirm "Use a new buffer")
+ (setq buffer (generate-new-buffer bname)))
+ ((eq async-shell-command-buffer 'new-buffer)
+ ;; It will create a new buffer.
+ (setq buffer (generate-new-buffer bname)))
+ ((eq async-shell-command-buffer 'confirm-rename-buffer)
+ ;; If will rename the buffer, query first.
+ (shell-command--same-buffer-confirm "Rename it")
+ (with-current-buffer buffer
+ (rename-uniquely))
+ (setq buffer (get-buffer-create bname)))
+ ((eq async-shell-command-buffer 'rename-buffer)
+ ;; It will rename the buffer.
+ (with-current-buffer buffer
+ (rename-uniquely))
+ (setq buffer (get-buffer-create bname)))))
+ (with-current-buffer buffer
+ (shell-command-save-pos-or-erase)
+ (setq default-directory directory)
+ (require 'shell)
+ (let ((process-environment
+ (append
+ (and (natnump async-shell-command-width)
+ (list
+ (format "COLUMNS=%d"
+ async-shell-command-width)))
+ (comint-term-environment)
+ process-environment)))
+ (setq proc
+ (start-process-shell-command "Shell" buffer command)))
+ (setq mode-line-process '(":%s"))
+ (shell-mode)
+ (setq-local revert-buffer-function
+ (lambda (&rest _)
+ (async-shell-command command buffer)))
+ (set-process-sentinel proc #'shell-command-sentinel)
+ ;; Use the comint filter for proper handling of
+ ;; carriage motion (see comint-inhibit-carriage-motion).
+ (set-process-filter proc #'comint-output-filter)
+ (if async-shell-command-display-buffer
+ ;; Display buffer immediately.
+ (display-buffer buffer '(nil (allow-no-window . t)))
+ ;; Defer displaying buffer until first process output.
+ ;; Use disposable named advice so that the buffer is
+ ;; displayed at most once per process lifetime.
+ (let ((nonce (make-symbol "nonce")))
+ (add-function :before (process-filter proc)
+ (lambda (proc _string)
+ (let ((buf (process-buffer proc)))
+ (when (buffer-live-p buf)
+ (remove-function (process-filter proc)
+ nonce)
+ (display-buffer buf))))
+ `((name . ,nonce)))))))
+ ;; Otherwise, command is executed synchronously.
+ (shell-command-on-region (point) (point) command
+ output-buffer nil error-buffer))))))
(defun shell-command--same-buffer-confirm (action)
(let ((help-form
@@ -6891,6 +6895,11 @@ The return value is t if Transient Mark mode is enabled and the
mark is active; furthermore, if `use-empty-active-region' is nil,
the region must not be empty. Otherwise, the return value is nil.
+If `use-empty-active-region' is non-nil, there is one further
+caveat: If the user has used `mouse-1' to set point, but used the
+mouse to move point to a different character yet, this function
+returns nil.
+
For some commands, it may be appropriate to ignore the value of
`use-empty-active-region'; in that case, use `region-active-p'.
@@ -6898,8 +6907,10 @@ Also see the convenience functions `use-region-beginning' and
`use-region-end', which may be handy when writing `interactive'
specs."
(and (region-active-p)
- (or use-empty-active-region (> (region-end) (region-beginning)))
- t))
+ (or (> (region-end) (region-beginning))
+ (and use-empty-active-region
+ (not (eq (car-safe last-input-event) 'down-mouse-1))
+ (not (mouse-movement-p last-input-event))))))
(defun region-active-p ()
"Return t if Transient Mark mode is enabled and the mark is active.
@@ -7019,7 +7030,7 @@ which is the window that will be redisplayed. When run, the `current-buffer'
is set to the buffer displayed in that window.")
(define-minor-mode cursor-face-highlight-mode
- "When enabled, respect the cursor-face property."
+ "When enabled, highlight text that has `cursor-face' property near point."
:global nil
(if cursor-face-highlight-mode
(add-hook 'pre-redisplay-functions
@@ -7830,7 +7841,9 @@ If NOERROR, don't signal an error if we can't move that many lines."
(defun line-move-1 (arg &optional noerror _to-end)
;; Don't run any point-motion hooks, and disregard intangibility,
;; for intermediate positions.
- (let ((inhibit-point-motion-hooks t)
+ (with-suppressed-warnings ((obsolete inhibit-point-motion-hooks))
+ (let ((outer-ipmh inhibit-point-motion-hooks)
+ (inhibit-point-motion-hooks t)
(opoint (point))
(orig-arg arg))
(if (consp temporary-goal-column)
@@ -7942,20 +7955,20 @@ If NOERROR, don't signal an error if we can't move that many lines."
;; point-left-hooks.
(let* ((npoint (prog1 (line-end-position)
(goto-char opoint)))
- (inhibit-point-motion-hooks nil))
+ (inhibit-point-motion-hooks outer-ipmh))
(goto-char npoint)))
((< arg 0)
;; If we did not move up as far as desired,
;; at least go to beginning of line.
(let* ((npoint (prog1 (line-beginning-position)
(goto-char opoint)))
- (inhibit-point-motion-hooks nil))
+ (inhibit-point-motion-hooks outer-ipmh))
(goto-char npoint)))
(t
(line-move-finish (or goal-column temporary-goal-column)
- opoint (> orig-arg 0)))))))
+ opoint (> orig-arg 0) (not outer-ipmh))))))))
-(defun line-move-finish (column opoint forward)
+(defun line-move-finish (column opoint forward &optional not-ipmh)
(let ((repeat t))
(while repeat
;; Set REPEAT to t to repeat the whole thing.
@@ -8006,42 +8019,44 @@ If NOERROR, don't signal an error if we can't move that many lines."
;; unnecessarily. Note that we move *forward* past intangible
;; text when the initial and final points are the same.
(goto-char new)
- (let ((inhibit-point-motion-hooks nil))
- (goto-char new)
-
- ;; If intangibility moves us to a different (later) place
- ;; in the same line, use that as the destination.
- (if (<= (point) line-end)
- (setq new (point))
- ;; If that position is "too late",
- ;; try the previous allowable position.
- ;; See if it is ok.
- (backward-char)
- (if (if forward
- ;; If going forward, don't accept the previous
- ;; allowable position if it is before the target line.
- (< line-beg (point))
- ;; If going backward, don't accept the previous
- ;; allowable position if it is still after the target line.
- (<= (point) line-end))
- (setq new (point))
- ;; As a last resort, use the end of the line.
- (setq new line-end))))
+ (with-suppressed-warnings ((obsolete inhibit-point-motion-hooks))
+ (let ((inhibit-point-motion-hooks (not not-ipmh)))
+ (goto-char new)
+
+ ;; If intangibility moves us to a different (later) place
+ ;; in the same line, use that as the destination.
+ (if (<= (point) line-end)
+ (setq new (point))
+ ;; If that position is "too late",
+ ;; try the previous allowable position.
+ ;; See if it is ok.
+ (backward-char)
+ (if (if forward
+ ;; If going forward, don't accept the previous
+ ;; allowable position if it is before the target line.
+ (< line-beg (point))
+ ;; If going backward, don't accept the previous
+ ;; allowable position if it is still after the target line.
+ (<= (point) line-end))
+ (setq new (point))
+ ;; As a last resort, use the end of the line.
+ (setq new line-end)))))
;; Now move to the updated destination, processing fields
;; as well as intangibility.
(goto-char opoint)
- (let ((inhibit-point-motion-hooks nil))
- (goto-char
- ;; Ignore field boundaries if the initial and final
- ;; positions have the same `field' property, even if the
- ;; fields are non-contiguous. This seems to be "nicer"
- ;; behavior in many situations.
- (if (eq (get-char-property new 'field)
- (get-char-property opoint 'field))
- new
- (constrain-to-field new opoint t t
- 'inhibit-line-move-field-capture))))
+ (with-suppressed-warnings ((obsolete inhibit-point-motion-hooks))
+ (let ((inhibit-point-motion-hooks (not not-ipmh)))
+ (goto-char
+ ;; Ignore field boundaries if the initial and final
+ ;; positions have the same `field' property, even if the
+ ;; fields are non-contiguous. This seems to be "nicer"
+ ;; behavior in many situations.
+ (if (eq (get-char-property new 'field)
+ (get-char-property opoint 'field))
+ new
+ (constrain-to-field new opoint t t
+ 'inhibit-line-move-field-capture)))))
;; If all this moved us to a different line,
;; retry everything within that new line.
diff --git a/lisp/startup.el b/lisp/startup.el
index a88cdd0d74d..e10d854c368 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -458,7 +458,8 @@ or `CVS', and any subdirectory that contains a file named `.nosearch'."
;; The Windows version doesn't report meaningful inode numbers, so
;; use the canonicalized absolute file name of the directory instead.
(setq attrs (or canonicalized
- (nthcdr 10 (file-attributes this-dir))))
+ (file-attribute-file-identifier
+ (file-attributes this-dir))))
(unless (member attrs normal-top-level-add-subdirs-inode-list)
(push attrs normal-top-level-add-subdirs-inode-list)
(dolist (file contents)
@@ -541,7 +542,7 @@ DIRS are relative."
(setq comp--compilable t))
(defvar native-comp-eln-load-path)
-(defvar native-comp-deferred-compilation)
+(defvar inhibit-automatic-native-compilation)
(defvar comp-enable-subr-trampolines)
(defvar startup--original-eln-load-path nil
@@ -578,6 +579,10 @@ the updated value."
It sets `command-line-processed', processes the command-line,
reads the initialization files, etc.
It is the default value of the variable `top-level'."
+ ;; Allow disabling automatic .elc->.eln processing.
+ (setq inhibit-automatic-native-compilation
+ (getenv "EMACS_INHIBIT_AUTOMATIC_NATIVE_COMPILATION"))
+
(if command-line-processed
(message internal--top-level-message)
(setq command-line-processed t)
@@ -596,7 +601,7 @@ It is the default value of the variable `top-level'."
;; in this session. This is necessary if libgccjit is not
;; available on MS-Windows, but Emacs was built with
;; native-compilation support.
- (setq native-comp-deferred-compilation nil
+ (setq inhibit-automatic-native-compilation t
comp-enable-subr-trampolines nil))
;; Form `native-comp-eln-load-path'.
diff --git a/lisp/strokes.el b/lisp/strokes.el
index 0edb20c2ebb..0f84588a41b 100644
--- a/lisp/strokes.el
+++ b/lisp/strokes.el
@@ -1359,11 +1359,9 @@ If STROKES-MAP is not given, `strokes-global-map' will be used instead."
"Return t if STROKE1's command name precedes STROKE2's in lexicographic order."
(string-lessp (cdr stroke1) (cdr stroke2)))
-(defvar strokes-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [(shift down-mouse-2)] #'strokes-do-stroke)
- (define-key map [(meta down-mouse-2)] #'strokes-do-complex-stroke)
- map))
+(defvar-keymap strokes-mode-map
+ "S-<down-mouse-2>" #'strokes-do-stroke
+ "M-<down-mouse-2>" #'strokes-do-complex-stroke)
;;;###autoload
(define-minor-mode strokes-mode
diff --git a/lisp/subr.el b/lisp/subr.el
index 8769fec2b95..56ce9fa69b9 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1562,6 +1562,21 @@ in the current Emacs session, then this function may return nil."
;; is this really correct? maybe remove mouse-movement?
(memq (event-basic-type object) '(mouse-1 mouse-2 mouse-3 mouse-movement)))
+(defun event--posn-at-point ()
+ ;; Use `window-point' for the case when the current buffer
+ ;; is temporarily switched to some other buffer (bug#50256)
+ (let* ((pos (window-point))
+ (posn (posn-at-point pos)))
+ (if (null posn) ;; `pos' is "out of sight".
+ (list (selected-window) pos '(0 . 0) 0)
+ ;; If `pos' is inside a chunk of text hidden by an `invisible'
+ ;; or `display' property, `posn-at-point' returns the position
+ ;; that *is* visible, whereas `event--posn-at-point' is used
+ ;; when we have a keyboard event, whose position is `point' even
+ ;; if that position is invisible.
+ (setf (nth 5 posn) pos)
+ posn)))
+
(defun event-start (event)
"Return the starting position of EVENT.
EVENT should be a mouse click, drag, or key press event. If
@@ -1588,10 +1603,7 @@ nil or (STRING . POSITION)'.
For more information, see Info node `(elisp)Click Events'."
(or (and (consp event) (nth 1 event))
- ;; Use `window-point' for the case when the current buffer
- ;; is temporarily switched to some other buffer (bug#50256)
- (posn-at-point (window-point))
- (list (selected-window) (window-point) '(0 . 0) 0)))
+ (event--posn-at-point)))
(defun event-end (event)
"Return the ending position of EVENT.
@@ -1599,10 +1611,7 @@ EVENT should be a click, drag, or key press event.
See `event-start' for a description of the value returned."
(or (and (consp event) (nth (if (consp (nth 2 event)) 2 1) event))
- ;; Use `window-point' for the case when the current buffer
- ;; is temporarily switched to some other buffer (bug#50256)
- (posn-at-point (window-point))
- (list (selected-window) (window-point) '(0 . 0) 0)))
+ (event--posn-at-point)))
(defsubst event-click-count (event)
"Return the multi-click count of EVENT, a click or drag event.
@@ -1828,7 +1837,12 @@ be a list of the form returned by `event-start' and `event-end'."
(set-advertised-calling-convention 'time-convert '(time form) "29.1")
;;;; Obsolescence declarations for variables, and aliases.
-
+(make-obsolete-variable
+ 'inhibit-point-motion-hooks
+ "use `cursor-intangible-mode' or `cursor-sensor-mode' instead"
+ ;; It's been announced as obsolete in NEWS and in the docstring since Emacs-25,
+ ;; but it's only been marked for compilation warnings since Emacs-29.
+ "25.1")
(make-obsolete-variable 'redisplay-dont-pause nil "24.5")
(make-obsolete-variable 'operating-system-release nil "28.1")
(make-obsolete-variable 'inhibit-changing-match-data 'save-match-data "29.1")
@@ -1859,6 +1873,17 @@ be a list of the form returned by `event-start' and `event-end'."
;; in warnings when using `values' in let-bindings.
;;(make-obsolete-variable 'values "no longer used" "28.1")
+(defvar max-specpdl-size 2500
+ "Former limit on specbindings, now without effect.
+This variable used to limit the size of the specpdl stack which,
+among other things, holds dynamic variable bindings and `unwind-protect'
+activations. To prevent runaway recursion, use `max-lisp-eval-depth'
+instead; it will indirectly limit the specpdl stack size as well.")
+(make-obsolete-variable 'max-specpdl-size nil "29.1")
+
+(make-obsolete-variable 'native-comp-deferred-compilation
+ 'inhibit-automatic-native-compilation "29.1")
+
;;;; Alternate names for functions - these are not being phased out.
@@ -2497,7 +2522,20 @@ The variable list SPEC is the same as in `if-let'."
(declare (indent 1) (debug if-let))
(list 'if-let spec (macroexp-progn body)))
+(defmacro while-let (spec &rest body)
+ "Bind variables according to SPEC and conditionally evaluate BODY.
+Evaluate each binding in turn, stopping if a binding value is nil.
+If all bindings are non-nil, eval BODY and repeat.
+The variable list SPEC is the same as in `if-let'."
+ (declare (indent 1) (debug if-let))
+ (let ((done (gensym "done")))
+ `(catch ',done
+ (while t
+ (if-let* ,spec
+ (progn
+ ,@body)
+ (throw ',done nil))))))
;; PUBLIC: find if the current mode derives from another.
@@ -3514,11 +3552,12 @@ like) while `y-or-n-p' is running)."
(if (or (zerop l) (eq ?\s (aref prompt (1- l))))
"" " ")
(if dialog ""
- (if help-form
- (format "(y, n or %s) "
- (key-description
- (vector help-char)))
- "(y or n) "))))))
+ (substitute-command-keys
+ (if help-form
+ (format "(\\`y', \\`n' or \\`%s') "
+ (key-description
+ (vector help-char)))
+ "(\\`y' or \\`n') ")))))))
;; Preserve the actual command that eventually called
;; `y-or-n-p' (otherwise `repeat' will be repeating
;; `exit-minibuffer').
@@ -4026,6 +4065,13 @@ system's shell."
Otherwise, return nil."
(or (stringp object) (null object)))
+(defun list-of-strings-p (object)
+ "Return t if OBJECT is nil or a list of strings."
+ (declare (pure t) (side-effect-free error-free))
+ (while (and (consp object) (stringp (car object)))
+ (setq object (cdr object)))
+ (null object))
+
(defun booleanp (object)
"Return t if OBJECT is one of the two canonical boolean values: t or nil.
Otherwise, return nil."
@@ -4823,16 +4869,26 @@ the function `undo--wrap-and-run-primitive-undo'."
(let ((undo--combining-change-calls t))
(if (not inhibit-modification-hooks)
(run-hook-with-args 'before-change-functions beg end))
- (let (;; (inhibit-modification-hooks t)
- (before-change-functions
- ;; Ugly Hack: if the body uses syntax-ppss/syntax-propertize
- ;; (e.g. via a regexp-search or sexp-movement triggering
- ;; on-the-fly syntax-propertize), make sure that this gets
- ;; properly refreshed after subsequent changes.
- (if (memq #'syntax-ppss-flush-cache before-change-functions)
- '(syntax-ppss-flush-cache)))
- after-change-functions)
- (setq result (funcall body)))
+ (let ((bcf before-change-functions)
+ (acf after-change-functions)
+ (local-bcf (local-variable-p 'before-change-functions))
+ (local-acf (local-variable-p 'after-change-functions)))
+ (unwind-protect
+ ;; FIXME: WIBNI we could just use `inhibit-modification-hooks'?
+ (progn
+ ;; Ugly Hack: if the body uses syntax-ppss/syntax-propertize
+ ;; (e.g. via a regexp-search or sexp-movement triggering
+ ;; on-the-fly syntax-propertize), make sure that this gets
+ ;; properly refreshed after subsequent changes.
+ (setq-local before-change-functions
+ (if (memq #'syntax-ppss-flush-cache bcf)
+ '(syntax-ppss-flush-cache)))
+ (setq-local after-change-functions nil)
+ (setq result (funcall body)))
+ (if local-bcf (setq before-change-functions bcf)
+ (kill-local-variable 'before-change-functions))
+ (if local-acf (setq after-change-functions acf)
+ (kill-local-variable 'after-change-functions))))
(when (not (eq buffer-undo-list t))
(let ((ap-elt
(list 'apply
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index cf5ae09a247..abefd996a8a 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -2411,6 +2411,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil,
(keymap-set tab-prefix-map "M" #'tab-move-to)
(keymap-set tab-prefix-map "G" #'tab-group)
(keymap-set tab-prefix-map "r" #'tab-rename)
+(keymap-set tab-prefix-map "^ f" #'tab-detach)
(keymap-set tab-prefix-map "RET" #'tab-switch)
(keymap-set tab-prefix-map "b" #'switch-to-buffer-other-tab)
(keymap-set tab-prefix-map "f" #'find-file-other-tab)
diff --git a/lisp/tab-line.el b/lisp/tab-line.el
index 3e3b4c95595..94e8f29a95f 100644
--- a/lisp/tab-line.el
+++ b/lisp/tab-line.el
@@ -135,45 +135,35 @@ function `tab-line-tab-face-group'."
:group 'tab-line-faces)
-(defvar tab-line-tab-map
- (let ((map (make-sparse-keymap)))
- (define-key map [tab-line down-mouse-1] 'tab-line-select-tab)
- (define-key map [tab-line mouse-2] 'tab-line-close-tab)
- (define-key map [tab-line down-mouse-3] 'tab-line-tab-context-menu)
- (define-key map "\C-m" 'tab-line-select-tab)
- map)
- "Local keymap for `tab-line-mode' window tabs.")
-
-(defvar tab-line-add-map
- (let ((map (make-sparse-keymap)))
- (define-key map [tab-line down-mouse-1] 'tab-line-new-tab)
- (define-key map [tab-line down-mouse-2] 'tab-line-new-tab)
- (define-key map "\C-m" 'tab-line-new-tab)
- map)
- "Local keymap to add `tab-line-mode' window tabs.")
-
-(defvar tab-line-tab-close-map
- (let ((map (make-sparse-keymap)))
- (define-key map [tab-line mouse-1] 'tab-line-close-tab)
- (define-key map [tab-line mouse-2] 'tab-line-close-tab)
- map)
- "Local keymap to close `tab-line-mode' window tabs.")
-
-(defvar tab-line-left-map
- (let ((map (make-sparse-keymap)))
- (define-key map [tab-line down-mouse-1] 'tab-line-hscroll-left)
- (define-key map [tab-line down-mouse-2] 'tab-line-hscroll-left)
- (define-key map "\C-m" 'tab-line-new-tab)
- map)
- "Local keymap to scroll `tab-line-mode' window tabs to the left.")
-
-(defvar tab-line-right-map
- (let ((map (make-sparse-keymap)))
- (define-key map [tab-line down-mouse-1] 'tab-line-hscroll-right)
- (define-key map [tab-line down-mouse-2] 'tab-line-hscroll-right)
- (define-key map "\C-m" 'tab-line-new-tab)
- map)
- "Local keymap to scroll `tab-line-mode' window tabs to the right.")
+(defvar-keymap tab-line-tab-map
+ :doc "Local keymap for `tab-line-mode' window tabs."
+ "<tab-line> <down-mouse-1>" #'tab-line-select-tab
+ "<tab-line> <mouse-2>" #'tab-line-close-tab
+ "<tab-line> <down-mouse-3>" #'tab-line-tab-context-menu
+ "RET" #'tab-line-select-tab)
+
+(defvar-keymap tab-line-add-map
+ :doc "Local keymap to add `tab-line-mode' window tabs."
+ "<tab-line> <down-mouse-1>" #'tab-line-new-tab
+ "<tab-line> <down-mouse-2>" #'tab-line-new-tab
+ "RET" #'tab-line-new-tab)
+
+(defvar-keymap tab-line-tab-close-map
+ :doc "Local keymap to close `tab-line-mode' window tabs."
+ "<tab-line> <mouse-1>" #'tab-line-close-tab
+ "<tab-line> <mouse-2>" #'tab-line-close-tab)
+
+(defvar-keymap tab-line-left-map
+ :doc "Local keymap to scroll `tab-line-mode' window tabs to the left."
+ "<tab-line> <down-mouse-1>" #'tab-line-hscroll-left
+ "<tab-line> <down-mouse-2>" #'tab-line-hscroll-left
+ "RET" #'tab-line-new-tab)
+
+(defvar-keymap tab-line-right-map
+ :doc "Local keymap to scroll `tab-line-mode' window tabs to the right."
+ "<tab-line> <down-mouse-1>" #'tab-line-hscroll-right
+ "<tab-line> <down-mouse-2>" #'tab-line-hscroll-right
+ "RET" #'tab-line-new-tab)
(defcustom tab-line-new-tab-choice t
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el
index 20ad6e1e46a..49d84319c51 100644
--- a/lisp/tar-mode.el
+++ b/lisp/tar-mode.el
@@ -169,7 +169,7 @@ This information is useful, but it takes screen space away from file names."
(defun tar-swap-data ()
"Swap buffer contents between current buffer and `tar-data-buffer'.
-Preserve the modified states of the buffers and set `buffer-swapped-with'."
+Preserve the modified states of the buffers and set `tar-data-swapped'."
(let ((data-buffer-modified-p (buffer-modified-p tar-data-buffer))
(current-buffer-modified-p (buffer-modified-p)))
(buffer-swap-text tar-data-buffer)
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el
index a16169d477f..24942d96c18 100644
--- a/lisp/term/haiku-win.el
+++ b/lisp/term/haiku-win.el
@@ -598,6 +598,45 @@ MODIFIERS is the internal modifier mask of the wheel movement."
;; the Deskbar will not, so kill ourself here.
(unless cancel-shutdown (kill-emacs))))
+;;;; Wallpaper support.
+
+
+(declare-function haiku-write-node-attribute "haikuselect.c")
+(declare-function haiku-send-message "haikuselect.c")
+
+(defun haiku-set-wallpaper (file)
+ "Make FILE the wallpaper.
+Set the desktop background to the image FILE, on all workspaces,
+with an offset of 0, 0."
+ (let ((encoded-file (encode-coding-string
+ (expand-file-name file)
+ (or file-name-coding-system
+ default-file-name-coding-system))))
+ ;; Write the necessary information to the desktop directory.
+ (haiku-write-node-attribute "/boot/home/Desktop"
+ "be:bgndimginfo"
+ (list '(type . 0)
+ '("be:bgndimginfoerasetext" bool t)
+ (list "be:bgndimginfopath" 'string
+ encoded-file)
+ '("be:bgndimginfoworkspaces" long
+ ;; This is a mask of all the
+ ;; workspaces the background
+ ;; image will be applied to. It
+ ;; is treated as an unsigned
+ ;; value by the Tracker, despite
+ ;; the type being signed.
+ -1)
+ ;; Don't apply an offset
+ '("be:bgndimginfooffset" point (0 . 0))
+ ;; Don't stretch or crop or anything
+ '("be:bgndimginfomode" long 0)
+ ;; Don't apply a set
+ '("be:bgndimginfoset" long 0)))
+ ;; Tell the tracker to redisplay the wallpaper.
+ (haiku-send-message "application/x-vnd.Be-TRAK"
+ (list (cons 'type (haiku-numeric-enum Tbgr))))))
+
;;;; Cursors.
diff --git a/lisp/term/pgtk-win.el b/lisp/term/pgtk-win.el
index b93e259d82a..20f15739167 100644
--- a/lisp/term/pgtk-win.el
+++ b/lisp/term/pgtk-win.el
@@ -371,6 +371,7 @@ This uses `icon-map-list' to map icon file names to stock icon names."
"Return the device class of NAME.
Users should not call this function; see `device-class' instead."
(cond
+ ((not name) nil)
((string-match-p "XTEST" name) 'test)
((string= "Virtual core pointer" name) 'core-pointer)
((string= "Virtual core keyboard" name) 'core-keyboard)
diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el
index 38266baa969..62684f52cc9 100644
--- a/lisp/term/x-win.el
+++ b/lisp/term/x-win.el
@@ -1573,45 +1573,68 @@ frames on all displays."
(defun x-device-class (name)
"Return the device class of NAME.
Users should not call this function; see `device-class' instead."
- (let ((downcased-name (downcase name)))
- (cond
- ((string-match-p "XTEST" name) 'test)
- ((string= "Virtual core pointer" name) 'core-pointer)
- ((string= "Virtual core keyboard" name) 'core-keyboard)
- ((string-match-p "eraser" downcased-name) 'eraser)
- ((string-match-p " pad" downcased-name) 'pad)
- ((or (or (string-match-p "wacom" downcased-name)
- (string-match-p "pen" downcased-name))
- (string-match-p "stylus" downcased-name))
- 'pen)
- ((or (string-prefix-p "xwayland-touch:" name)
- (string-match-p "touchscreen" downcased-name))
- 'touchscreen)
- ((or (string-match-p "trackpoint" downcased-name)
- (string-match-p "stick" downcased-name))
- 'trackpoint)
- ((or (string-match-p "mouse" downcased-name)
- (string-match-p "optical" downcased-name)
- (string-match-p "pointer" downcased-name))
- 'mouse)
- ((string-match-p "cursor" downcased-name) 'puck)
- ((or (string-match-p "keyboard" downcased-name)
- ;; One of my cheap keyboards is really named this...
- (string= name "USB USB Keykoard"))
- 'keyboard)
- ((string-match-p "button" downcased-name) 'power-button)
- ((string-match-p "touchpad" downcased-name) 'touchpad)
- ((or (string-match-p "midi" downcased-name)
- (string-match-p "piano" downcased-name))
- 'piano)
- ((or (string-match-p "wskbd" downcased-name) ; NetBSD/OpenBSD
- (and (string-match-p "/dev" downcased-name)
- (string-match-p "kbd" downcased-name)))
- 'keyboard))))
+ (and name
+ (let ((downcased-name (downcase name)))
+ (cond
+ ((string-match-p "XTEST" name) 'test)
+ ((string= "Virtual core pointer" name) 'core-pointer)
+ ((string= "Virtual core keyboard" name) 'core-keyboard)
+ ((string-match-p "eraser" downcased-name) 'eraser)
+ ((string-match-p " pad" downcased-name) 'pad)
+ ((or (or (string-match-p "wacom" downcased-name)
+ (string-match-p "pen" downcased-name))
+ (string-match-p "stylus" downcased-name))
+ 'pen)
+ ((or (string-prefix-p "xwayland-touch:" name)
+ (string-match-p "touchscreen" downcased-name))
+ 'touchscreen)
+ ((or (string-match-p "trackpoint" downcased-name)
+ (string-match-p "stick" downcased-name))
+ 'trackpoint)
+ ((or (string-match-p "mouse" downcased-name)
+ (string-match-p "optical" downcased-name)
+ (string-match-p "pointer" downcased-name))
+ 'mouse)
+ ((string-match-p "cursor" downcased-name) 'puck)
+ ((or (string-match-p "keyboard" downcased-name)
+ ;; One of my cheap keyboards is really named this...
+ (string= name "USB USB Keykoard"))
+ 'keyboard)
+ ((string-match-p "button" downcased-name) 'power-button)
+ ((string-match-p "touchpad" downcased-name) 'touchpad)
+ ((or (string-match-p "midi" downcased-name)
+ (string-match-p "piano" downcased-name))
+ 'piano)
+ ((or (string-match-p "wskbd" downcased-name) ; NetBSD/OpenBSD
+ (and (string-match-p "/dev" downcased-name)
+ (string-match-p "kbd" downcased-name)))
+ 'keyboard)))))
(setq x-dnd-movement-function #'x-dnd-movement)
(setq x-dnd-unsupported-drop-function #'x-dnd-handle-unsupported-drop)
+(defvar x-input-coding-function)
+
+(defun x-get-input-coding-system (x-locale)
+ "Return a coding system for the locale X-LOCALE.
+Return a coding system that is able to decode text sent with the
+X input method locale X-LOCALE, or nil if no coding system was
+found."
+ (if (equal x-locale "C")
+ ;; Treat the C locale specially, as it means "ascii" under X.
+ 'ascii
+ (let ((locale (locale-translate (downcase x-locale))))
+ (or (locale-name-match locale locale-preferred-coding-systems)
+ (when locale
+ (if (string-match "\\.\\([^@]+\\)" locale)
+ (locale-charset-to-coding-system
+ (match-string 1 locale))))
+ (let ((language-name
+ (locale-name-match locale locale-language-names)))
+ (and (consp language-name) (cdr language-name)))))))
+
+(setq x-input-coding-function #'x-get-input-coding-system)
+
(provide 'x-win)
(provide 'term/x-win)
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 8135d40d261..f4b557f443f 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -1,7 +1,6 @@
;;; bibtex.el --- BibTeX mode for GNU Emacs -*- lexical-binding: t -*-
-;; Copyright (C) 1992, 1994-1999, 2001-2022 Free Software Foundation,
-;; Inc.
+;; Copyright (C) 1992-2022 Free Software Foundation, Inc.
;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
;; Bengt Martensson <bengt@mathematik.uni-Bremen.de>
@@ -29,14 +28,13 @@
;;; Commentary:
-;; Major mode for editing and validating BibTeX files.
+;; Major mode for editing and validating BibTeX files.
-;; Usage:
-;; See documentation for `bibtex-mode' or type "M-x describe-mode"
-;; when you are in BibTeX mode.
+;; See documentation for `bibtex-mode' or type `M-x describe-mode'
+;; when you are in BibTeX mode.
-;; Todo:
-;; Distribute texinfo file.
+;; Todo:
+;; Distribute texinfo file.
;;; Code:
@@ -1548,65 +1546,65 @@ Set this variable before loading BibTeX mode."
st)
"Syntax table used in BibTeX mode buffers.")
-(defvar bibtex-mode-map
- (let ((km (make-sparse-keymap)))
- ;; The Key `C-c&' is reserved for reftex.el
- (define-key km "\t" 'bibtex-find-text)
- (define-key km "\n" 'bibtex-next-field)
- (define-key km [remap forward-paragraph] 'bibtex-next-entry)
- (define-key km [remap backward-paragraph] 'bibtex-previous-entry)
- (define-key km "\M-\t" 'completion-at-point)
- (define-key km "\C-c\"" 'bibtex-remove-delimiters)
- (define-key km "\C-c{" 'bibtex-remove-delimiters)
- (define-key km "\C-c}" 'bibtex-remove-delimiters)
- (define-key km "\C-c\C-c" 'bibtex-clean-entry)
- (define-key km "\C-c\C-q" 'bibtex-fill-entry)
- (define-key km "\C-c\C-s" 'bibtex-search-entry)
- (define-key km "\C-c\C-x" 'bibtex-search-crossref)
- (define-key km "\C-c\C-t" 'bibtex-copy-summary-as-kill)
- (define-key km "\C-c?" 'bibtex-print-help-message)
- (define-key km "\C-c\C-p" 'bibtex-pop-previous)
- (define-key km "\C-c\C-n" 'bibtex-pop-next)
- (define-key km "\C-c\C-k" 'bibtex-kill-field)
- (define-key km "\C-c\M-k" 'bibtex-copy-field-as-kill)
- (define-key km "\C-c\C-w" 'bibtex-kill-entry)
- (define-key km "\C-c\M-w" 'bibtex-copy-entry-as-kill)
- (define-key km "\C-c\C-y" 'bibtex-yank)
- (define-key km "\C-c\M-y" 'bibtex-yank-pop)
- (define-key km "\C-c\C-d" 'bibtex-empty-field)
- (define-key km "\C-c\C-f" 'bibtex-make-field)
- (define-key km "\C-c\C-u" 'bibtex-entry-update)
- (define-key km "\C-c$" 'bibtex-ispell-abstract)
- (define-key km "\M-\C-a" 'bibtex-beginning-of-entry)
- (define-key km "\M-\C-e" 'bibtex-end-of-entry)
- (define-key km "\C-\M-l" 'bibtex-reposition-window)
- (define-key km "\C-\M-h" 'bibtex-mark-entry)
- (define-key km "\C-c\C-b" 'bibtex-entry)
- (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
- (define-key km "\C-c\C-rw" 'widen)
- (define-key km "\C-c\C-l" 'bibtex-url)
- (define-key km "\C-c\C-a" 'bibtex-search-entries)
- (define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
- (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
- (define-key km "\C-c\C-ei" 'bibtex-InCollection)
- (define-key km "\C-c\C-eI" 'bibtex-InBook)
- (define-key km "\C-c\C-e\C-a" 'bibtex-Article)
- (define-key km "\C-c\C-e\C-b" 'bibtex-InBook)
- (define-key km "\C-c\C-eb" 'bibtex-Book)
- (define-key km "\C-c\C-eB" 'bibtex-Booklet)
- (define-key km "\C-c\C-e\C-c" 'bibtex-InCollection)
- (define-key km "\C-c\C-e\C-m" 'bibtex-Manual)
- (define-key km "\C-c\C-em" 'bibtex-MastersThesis)
- (define-key km "\C-c\C-eM" 'bibtex-Misc)
- (define-key km "\C-c\C-e\C-p" 'bibtex-InProceedings)
- (define-key km "\C-c\C-ep" 'bibtex-Proceedings)
- (define-key km "\C-c\C-eP" 'bibtex-PhdThesis)
- (define-key km "\C-c\C-e\M-p" 'bibtex-Preamble)
- (define-key km "\C-c\C-e\C-s" 'bibtex-String)
- (define-key km "\C-c\C-e\C-t" 'bibtex-TechReport)
- (define-key km "\C-c\C-e\C-u" 'bibtex-Unpublished)
- km)
- "Keymap used in BibTeX mode.")
+(defvar-keymap bibtex-mode-map
+ :doc "Keymap used in BibTeX mode."
+ ;; The Key `C-c &' is reserved for reftex.el
+ "TAB" #'bibtex-find-text
+ "C-j" #'bibtex-next-field
+ "M-TAB" #'completion-at-point
+ "C-c \"" #'bibtex-remove-delimiters
+ "C-c {" #'bibtex-remove-delimiters
+ "C-c }" #'bibtex-remove-delimiters
+ "C-c C-c" #'bibtex-clean-entry
+ "C-c C-q" #'bibtex-fill-entry
+ "C-c C-s" #'bibtex-search-entry
+ "C-c C-x" #'bibtex-search-crossref
+ "C-c C-t" #'bibtex-copy-summary-as-kill
+ "C-c ?" #'bibtex-print-help-message
+ "C-c C-p" #'bibtex-pop-previous
+ "C-c C-n" #'bibtex-pop-next
+ "C-c C-k" #'bibtex-kill-field
+ "C-c M-k" #'bibtex-copy-field-as-kill
+ "C-c C-w" #'bibtex-kill-entry
+ "C-c M-w" #'bibtex-copy-entry-as-kill
+ "C-c C-y" #'bibtex-yank
+ "C-c M-y" #'bibtex-yank-pop
+ "C-c C-d" #'bibtex-empty-field
+ "C-c C-f" #'bibtex-make-field
+ "C-c C-u" #'bibtex-entry-update
+ "C-c $" #'bibtex-ispell-abstract
+ "C-M-a" #'bibtex-beginning-of-entry
+ "C-M-e" #'bibtex-end-of-entry
+ "C-M-l" #'bibtex-reposition-window
+ "C-M-h" #'bibtex-mark-entry
+ "C-c C-b" #'bibtex-entry
+ "C-c C-r n" #'bibtex-narrow-to-entry
+ "C-c C-r w" #'widen
+ "C-c C-l" #'bibtex-url
+ "C-c C-a" #'bibtex-search-entries
+ "C-c C-o" #'bibtex-remove-OPT-or-ALT
+ ;; Most below functions seem to be undefined, which makes the
+ ;; byte-compiler warn if we quote them with #'.
+ "C-c C-e TAB" 'bibtex-InProceedings
+ "C-c C-e i" 'bibtex-InCollection
+ "C-c C-e I" 'bibtex-InBook
+ "C-c C-e C-a" 'bibtex-Article
+ "C-c C-e C-b" 'bibtex-InBook
+ "C-c C-e b" 'bibtex-Book
+ "C-c C-e B" 'bibtex-Booklet
+ "C-c C-e C-c" 'bibtex-InCollection
+ "C-c C-e RET" 'bibtex-Manual
+ "C-c C-e m" 'bibtex-MastersThesis
+ "C-c C-e M" 'bibtex-Misc
+ "C-c C-e C-p" 'bibtex-InProceedings
+ "C-c C-e p" 'bibtex-Proceedings
+ "C-c C-e P" 'bibtex-PhdThesis
+ "C-c C-e M-p" #'bibtex-Preamble
+ "C-c C-e C-s" #'bibtex-String
+ "C-c C-e C-t" 'bibtex-TechReport
+ "C-c C-e C-u" 'bibtex-Unpublished
+ "<remap> <forward-paragraph>" #'bibtex-next-entry
+ "<remap> <backward-paragraph>" #'bibtex-previous-entry)
(easy-menu-define bibtex-edit-menu bibtex-mode-map
"BibTeX-Edit Menu in BibTeX mode."
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
index 6bf96deaccb..d9decae4df6 100644
--- a/lisp/textmodes/emacs-news-mode.el
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -80,6 +80,7 @@
outline-minor-mode-cycle t
outline-minor-mode-highlight 'append)
(outline-minor-mode)
+ (setq-local imenu-generic-expression outline-imenu-generic-expression)
(emacs-etc--hide-local-variables))
;;;###autoload
@@ -276,6 +277,17 @@ documentation marks on the previous line."
(forward-line -1))
(open-line n))
+(defun emacs-news-delete-temporary-markers ()
+ "Delete any temporary markers.
+This is used when preparing a new release of Emacs."
+ (interactive nil emacs-news-mode)
+ (goto-char (point-min))
+ (re-search-forward "^Temporary note:$")
+ (forward-line -1)
+ (delete-region (point) (save-excursion (forward-paragraph) (point)))
+ (while (re-search-forward (rx bol (or "+++" "---") eol) nil t)
+ (delete-line)))
+
(provide 'emacs-news-mode)
;;; emacs-news-mode.el ends here
diff --git a/lisp/textmodes/enriched.el b/lisp/textmodes/enriched.el
index 935be06812f..26f22a9a4a7 100644
--- a/lisp/textmodes/enriched.el
+++ b/lisp/textmodes/enriched.el
@@ -325,8 +325,7 @@ the region, and the START and END of each region."
;;;###autoload
(defun enriched-encode (from to orig-buf)
(if enriched-verbose (message "Enriched: encoding document..."))
- (let ((inhibit-read-only t)
- (inhibit-point-motion-hooks t))
+ (let ((inhibit-read-only t))
(save-restriction
(narrow-to-region from to)
(delete-to-left-margin)
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el
index a893bc7b9ce..a66b72cfd06 100644
--- a/lisp/textmodes/flyspell.el
+++ b/lisp/textmodes/flyspell.el
@@ -425,11 +425,9 @@ like <img alt=\"Some thing.\">."
;;*---------------------------------------------------------------------*/
;;* The minor mode declaration. */
;;*---------------------------------------------------------------------*/
-(defvar flyspell-mouse-map
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-2] 'flyspell-correct-word)
- map)
- "Keymap for Flyspell to put on erroneous words.")
+(defvar-keymap flyspell-mouse-map
+ :doc "Keymap for Flyspell to put on erroneous words."
+ "<mouse-2>" #'flyspell-correct-word)
(defvar flyspell-mode-map
(let ((map (make-sparse-keymap)))
@@ -1034,7 +1032,6 @@ Mostly we check word delimiters."
(defun flyspell-word-search-backward (word bound &optional ignore-case)
(save-excursion
(let* ((r '())
- (inhibit-point-motion-hooks t)
(flyspell-not-casechars (flyspell-get-not-casechars))
(bound (if (and bound
(> bound (point-min)))
@@ -1068,7 +1065,6 @@ Mostly we check word delimiters."
(defun flyspell-word-search-forward (word bound)
(save-excursion
(let* ((r '())
- (inhibit-point-motion-hooks t)
(flyspell-not-casechars (flyspell-get-not-casechars))
(bound (if (and bound
(< bound (point-max)))
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index 4b5ed98ecc9..b3fb326cf9b 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -740,7 +740,8 @@ Otherwise returns the library directory name, if that is defined."
"Execute the forms in BODY with a reasonable `default-directory'."
(declare (indent 0) (debug t))
`(let ((default-directory default-directory))
- (unless (file-accessible-directory-p default-directory)
+ (unless (and (not (file-remote-p default-directory))
+ (file-accessible-directory-p default-directory))
(setq default-directory (expand-file-name "~/")))
,@body))
diff --git a/lisp/textmodes/less-css-mode.el b/lisp/textmodes/less-css-mode.el
index a0462756b0b..bfb5566e896 100644
--- a/lisp/textmodes/less-css-mode.el
+++ b/lisp/textmodes/less-css-mode.el
@@ -24,7 +24,7 @@
;;; Commentary:
;; This mode provides syntax highlighting for Less CSS files
-;; (http://lesscss.org/), plus optional support for compilation of
+;; (https://lesscss.org/), plus optional support for compilation of
;; .less files to .css files at the time they are saved: use
;; `less-css-compile-at-save' to enable this.
;;
@@ -209,10 +209,8 @@ directory by default."
(modify-syntax-entry ?. "'" st)
st))
-(defvar less-css-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-c" #'less-css-compile)
- map))
+(defvar-keymap less-css-mode-map
+ "C-c C-c" #'less-css-compile)
;;;###autoload (add-to-list 'auto-mode-alist '("\\.less\\'" . less-css-mode))
;;;###autoload
diff --git a/lisp/textmodes/page-ext.el b/lisp/textmodes/page-ext.el
index 6b71f26e4f2..05c02308e52 100644
--- a/lisp/textmodes/page-ext.el
+++ b/lisp/textmodes/page-ext.el
@@ -1,7 +1,6 @@
;;; page-ext.el --- extended page handling commands -*- lexical-binding:t -*-
-;; Copyright (C) 1990-1991, 1993-1994, 2001-2022 Free Software
-;; Foundation, Inc.
+;; Copyright (C) 1990-2022 Free Software Foundation, Inc.
;; Author: Robert J. Chassell <bob@gnu.org>
;; (according to ack.texi)
@@ -25,20 +24,20 @@
;;; Commentary:
;; You may use these commands to handle an address list or other
-;; small data base.
+;; small database.
;;; Summary
;; The current page commands are:
-;; forward-page C-x ]
-;; backward-page C-x [
-;; narrow-to-page C-x p
-;; count-lines-page C-x l
-;; mark-page C-x C-p (change this to C-x C-p C-m)
-;; sort-pages not bound
-;; what-page not bound
+;; `forward-page' C-x ]
+;; `backward-page' C-x [
+;; `narrow-to-page' C-x p
+;; `count-lines-page' C-x l
+;; `mark-page' C-x C-p (change this to C-x C-p C-m)
+;; `sort-pages' not bound
+;; `what-page' not bound
;; The new page handling commands all use `C-x C-p' as a prefix. This
;; means that the key binding for `mark-page' must be changed.
@@ -47,15 +46,15 @@
;; New page handling commands:
-;; pages-next-page C-x C-p C-n
-;; pages-previous-page C-x C-p C-p
-;; pages-search C-x C-p C-s
-;; pages-add-new-page C-x C-p C-a
-;; pages-sort-buffer C-x C-p s
-;; pages-set-delimiter C-x C-p C-l
-;; pages-directory C-x C-p C-d
-;; pages-directory-for-addresses C-x C-p d
-;; pages-directory-goto C-c C-c
+;; `pages-next-page' C-x C-p C-n
+;; `pages-previous-page' C-x C-p C-p
+;; `pages-search' C-x C-p C-s
+;; `pages-add-new-page' C-x C-p C-a
+;; `pages-sort-buffer' C-x C-p s
+;; `pages-set-delimiter' C-x C-p C-l
+;; `pages-directory' C-x C-p C-d
+;; `pages-directory-for-addresses' C-x C-p d
+;; `pages-directory-goto' C-c C-c
;;; Using the page commands
@@ -103,8 +102,8 @@
;;
;; 2. The first line of text in each entry is the `heading line'; it
;; will appear in the pages-directory-buffer which is constructed
-;; using the `C-x C-p C-d' (pages-directory) command or the `C-x
-;; C-p d' (pages-directory-for-addresses) command.
+;; using the `C-x C-p C-d' (`pages-directory') command or the
+;; `C-x C-p d' (`pages-directory-for-addresses') command.
;;
;; The heading line may be on the same line as the page-delimiter
;; or it may follow after. It is the first non-blank line on the
@@ -163,17 +162,18 @@
;; `pages-previous-page', `pages-add-new-page', `mark-page', and `pages-search'
;; commands.
-;; You may use either the `C-x C-p d' (pages-directory-for-addresses)
-;; or the `C-x C-p C-d' (pages-directory) command to construct and
+;; You may use either the `C-x C-p d' (`pages-directory-for-addresses')
+;; or the `C-x C-p C-d' (`pages-directory') command to construct and
;; display a directory of all the heading lines.
;; In the directory, you may position the cursor over a heading line
-;; and type `C-c C-c' (pages-directory-goto) to go to the entry to
+;; and type `C-c C-c' (`pages-directory-goto') to go to the entry to
;; which it refers in the pages buffer.
-;; You can type `C-c C-p C-a' (pages-add-new-page) to add a new entry in the
-;; pages buffer or address file. This is the same command you use to
-;; add a new entry when you are in the pages buffer or address file.
+;; You can type `C-c C-p C-a' (`pages-add-new-page') to add a new
+;; entry in the pages buffer or address file. This is the same
+;; command you use to add a new entry when you are in the pages buffer
+;; or address file.
;; If you wish, you may create several different directories,
;; one for each different buffer.
diff --git a/lisp/textmodes/picture.el b/lisp/textmodes/picture.el
index e8c1e6b14f2..ab211fdd7bf 100644
--- a/lisp/textmodes/picture.el
+++ b/lisp/textmodes/picture.el
@@ -1,6 +1,6 @@
;;; picture.el --- "Picture mode" -- editing using quarter-plane screen model -*- lexical-binding: t -*-
-;; Copyright (C) 1985, 1994, 2001-2022 Free Software Foundation, Inc.
+;; Copyright (C) 1985-2022 Free Software Foundation, Inc.
;; Author: K. Shane Hartman
;; Maintainer: emacs-devel@gnu.org
@@ -23,9 +23,9 @@
;;; Commentary:
-;; This code provides the picture-mode commands documented in the Emacs
+;; This code provides the `picture-mode' commands documented in the Emacs
;; manual. The screen is treated as a semi-infinite quarter-plane with
-;; support for rectangle operations and `etch-a-sketch' character
+;; support for rectangle operations and "etch-a-sketch" character
;; insertion in any of eight directions.
;;; Code:
@@ -96,7 +96,7 @@ If scan reaches end of buffer, stop there without error."
(defun picture-forward-column (arg &optional interactive)
"Move cursor right, making whitespace if necessary.
-With argument, move that many columns."
+With prefix argument ARG, move that many columns."
(interactive "^p\nd")
(let (deactivate-mark)
(picture-update-desired-column interactive)
@@ -110,14 +110,14 @@ With argument, move that many columns."
(defun picture-backward-column (arg &optional interactive)
"Move cursor left, making whitespace if necessary.
-With argument, move that many columns."
+With prefix argument ARG, move that many columns."
(interactive "^p\nd")
(picture-update-desired-column interactive)
(picture-forward-column (- arg)))
(defun picture-move-down (arg)
"Move vertically down, making whitespace if necessary.
-With argument, move that many lines."
+With prefix argument ARG, move that many lines."
(interactive "^p")
(let (deactivate-mark)
(picture-update-desired-column nil)
@@ -134,7 +134,7 @@ With argument, move that many lines."
(defun picture-move-up (arg)
"Move vertically up, making whitespace if necessary.
-With argument, move that many lines."
+With prefix argument ARG, move that many lines."
(interactive "^p")
(picture-update-desired-column nil)
(picture-move-down (- arg)))
@@ -161,36 +161,36 @@ With argument, move that many lines."
(defun picture-movement-nw (&optional arg)
"Move up and left after self-inserting character in Picture mode.
-With prefix argument, move up and two-column left."
+With prefix argument ARG, move up and two-column left."
(interactive "P")
(picture-set-motion -1 (if arg -2 -1)))
(defun picture-movement-ne (&optional arg)
"Move up and right after self-inserting character in Picture mode.
-With prefix argument, move up and two-column right."
+With prefix argument ARG, move up and two-column right."
(interactive "P")
(picture-set-motion -1 (if arg 2 1)))
(defun picture-movement-sw (&optional arg)
"Move down and left after self-inserting character in Picture mode.
-With prefix argument, move down and two-column left."
+With prefix argument ARG, move down and two-column left."
(interactive "P")
(picture-set-motion 1 (if arg -2 -1)))
(defun picture-movement-se (&optional arg)
"Move down and right after self-inserting character in Picture mode.
-With prefix argument, move down and two-column right."
+With prefix argument ARG, move down and two-column right."
(interactive "P")
(picture-set-motion 1 (if arg 2 1)))
-(defun picture-set-motion (vert horiz)
+(defun picture-set-motion (vertical horizontal)
"Set VERTICAL and HORIZONTAL increments for movement in Picture mode.
The mode line is updated to reflect the current direction."
- (setq picture-vertical-step vert
- picture-horizontal-step horiz)
+ (setq picture-vertical-step vertical
+ picture-horizontal-step horizontal)
(setq mode-name
(format "Picture:%s"
- (nth (+ 2 (% horiz 3) (* 5 (1+ (% vert 2))))
+ (nth (+ 2 (% horizontal 3) (* 5 (1+ (% vertical 2))))
'(wnw nw up ne ene Left left none right Right
wsw sw down se ese))))
(force-mode-line-update)
@@ -305,9 +305,9 @@ Use \"\\[command-apropos] picture-movement\" to see those commands."
(defun picture-clear-line (arg)
"Clear out rest of line; if at end of line, advance to next line.
-Cleared-out line text goes into the kill ring, as do newlines that are
-advanced over. With argument, clear out (and save in kill ring) that
-many lines."
+Cleared-out line text goes into the kill ring, as do newlines
+that are advanced over. With prefix argument ARG, clear out (and
+save in kill ring) that many lines."
(interactive "P")
(if arg
(progn
@@ -320,7 +320,8 @@ many lines."
(defun picture-newline (arg)
"Move to the beginning of the following line.
-With argument, moves that many lines (up, if negative argument);
+With prefix argument ARG, move that many lines (up, if negative
+argument);
always moves to the beginning of a line."
(interactive "^p")
(let ((start (point))
@@ -466,8 +467,11 @@ If no such character is found, move to beginning of line."
(defun picture-tab (&optional arg)
"Tab transparently (just move point) to next tab stop.
-With prefix arg, overwrite the traversed text with spaces. The tab stop
-list can be changed by \\[picture-set-tab-stops] and \\[edit-tab-stops].
+With prefix argument ARG, overwrite the traversed text with
+spaces. The tab stop list can be changed by \
+\\<picture-mode-map>\\[picture-set-tab-stops] and
+\\[edit-tab-stops].
+
See also documentation for variable `picture-tab-chars'."
(interactive "^P")
(let* ((opoint (point)))
@@ -515,10 +519,11 @@ Interactively, reads the register using `register-read-with-preview'."
(defun picture-yank-rectangle (&optional insertp)
"Overlay rectangle saved by \\[picture-clear-rectangle].
-The rectangle is positioned with upper left corner at point, overwriting
-existing text. With prefix argument, the rectangle is inserted instead,
-shifting existing text. Leaves mark at one corner of rectangle and
-point at the other (diagonally opposed) corner."
+The rectangle is positioned with upper left corner at point,
+overwriting existing text. With prefix argument INSERTP, the
+rectangle is inserted instead, shifting existing text. Leave
+mark at one corner of rectangle and point at the
+other (diagonally opposed) corner."
(interactive "P")
(if (not (consp picture-killed-rectangle))
(error "No rectangle saved")
@@ -536,10 +541,11 @@ regardless of where you click."
(defun picture-yank-rectangle-from-register (register &optional insertp)
"Overlay rectangle saved in REGISTER.
-The rectangle is positioned with upper left corner at point, overwriting
-existing text. With prefix argument, the rectangle is
-inserted instead, shifting existing text. Leaves mark at one corner
-of rectangle and point at the other (diagonally opposed) corner.
+The rectangle is positioned with upper left corner at point,
+overwriting existing text. With prefix argument INSERTP, the
+rectangle is inserted instead, shifting existing text. Leave
+mark at one corner of rectangle and point at the
+other (diagonally opposed) corner.
Interactively, reads the register using `register-read-with-preview'."
(interactive (list (register-read-with-preview "Rectangle from register: ")
@@ -552,7 +558,7 @@ Interactively, reads the register using `register-read-with-preview'."
(defun picture-insert-rectangle (rectangle &optional insertp)
"Overlay RECTANGLE with upper left corner at point.
Optional argument INSERTP, if non-nil causes RECTANGLE to be inserted.
-Leaves the region surrounding the rectangle."
+Leave the region surrounding the rectangle."
(let ((indent-tabs-mode nil))
(if (not insertp)
(save-excursion
@@ -570,7 +576,7 @@ Leaves the region surrounding the rectangle."
(if (= (current-column) 0) 1 0)))
(defun picture-draw-rectangle (start end)
- "Draw a rectangle around region."
+ "Draw a rectangle around region from START to END."
(interactive "*r") ; start will be less than end
(let* ((sl (picture-current-line))
(sc (current-column))
@@ -615,61 +621,57 @@ Leaves the region surrounding the rectangle."
(defalias 'picture-delete-char 'delete-char)
-(defvar picture-mode-map
- (let ((map (make-keymap)))
- (define-key map [remap self-insert-command] 'picture-self-insert)
- (define-key map [remap completion-separator-self-insert-command]
- 'picture-self-insert)
- (define-key map [remap completion-separator-self-insert-autofilling]
- 'picture-self-insert)
- (define-key map [remap forward-char] 'picture-forward-column)
- (define-key map [remap right-char] 'picture-forward-column)
- (define-key map [remap backward-char] 'picture-backward-column)
- (define-key map [remap left-char] 'picture-backward-column)
- (define-key map [remap delete-char] 'picture-clear-column)
- ;; There are two possibilities for what is normally on DEL.
- (define-key map [remap backward-delete-char-untabify]
- 'picture-backward-clear-column)
- (define-key map [remap delete-backward-char] 'picture-backward-clear-column)
- (define-key map [remap kill-line] 'picture-clear-line)
- (define-key map [remap open-line] 'picture-open-line)
- (define-key map [remap newline] 'picture-newline)
- (define-key map [remap newline-and-indent] 'picture-duplicate-line)
- (define-key map [remap next-line] 'picture-move-down)
- (define-key map [remap previous-line] 'picture-move-up)
- (define-key map [remap move-beginning-of-line] 'picture-beginning-of-line)
- (define-key map [remap move-end-of-line] 'picture-end-of-line)
- (define-key map [remap mouse-set-point] 'picture-mouse-set-point)
- (define-key map "\C-c\C-d" 'picture-delete-char)
- (define-key map "\t" 'picture-tab)
- (define-key map "\e\t" 'picture-tab-search)
- (define-key map "\C-c\t" 'picture-set-tab-stops)
- (define-key map "\C-c\C-k" 'picture-clear-rectangle)
- (define-key map "\C-c\C-w" 'picture-clear-rectangle-to-register)
- (define-key map "\C-c\C-y" 'picture-yank-rectangle)
- (define-key map "\C-c\C-x" 'picture-yank-rectangle-from-register)
- (define-key map "\C-c\C-r" 'picture-draw-rectangle)
- (define-key map "\C-c\C-c" 'picture-mode-exit)
- (define-key map "\C-c\C-f" 'picture-motion)
- (define-key map "\C-c\C-b" 'picture-motion-reverse)
- (define-key map "\C-c<" 'picture-movement-left)
- (define-key map "\C-c>" 'picture-movement-right)
- (define-key map "\C-c^" 'picture-movement-up)
- (define-key map "\C-c." 'picture-movement-down)
- (define-key map "\C-c`" 'picture-movement-nw)
- (define-key map "\C-c'" 'picture-movement-ne)
- (define-key map "\C-c/" 'picture-movement-sw)
- (define-key map "\C-c\\" 'picture-movement-se)
- (define-key map [(control ?c) left] 'picture-movement-left)
- (define-key map [(control ?c) right] 'picture-movement-right)
- (define-key map [(control ?c) up] 'picture-movement-up)
- (define-key map [(control ?c) down] 'picture-movement-down)
- (define-key map [(control ?c) home] 'picture-movement-nw)
- (define-key map [(control ?c) prior] 'picture-movement-ne)
- (define-key map [(control ?c) end] 'picture-movement-sw)
- (define-key map [(control ?c) next] 'picture-movement-se)
- map)
- "Keymap used in `picture-mode'.")
+(defvar-keymap picture-mode-map
+ :doc "Keymap used in `picture-mode'."
+ :full t
+ "<remap> <self-insert-command>" #'picture-self-insert
+ "<remap> <completion-separator-self-insert-command>" #'picture-self-insert
+ "<remap> <completion-separator-self-insert-autofilling>" #'picture-self-insert
+ "<remap> <forward-char>" #'picture-forward-column
+ "<remap> <right-char>" #'picture-forward-column
+ "<remap> <backward-char>" #'picture-backward-column
+ "<remap> <left-char>" #'picture-backward-column
+ "<remap> <delete-char>" #'picture-clear-column
+ ;; There are two possibilities for what is normally on DEL.
+ "<remap> <backward-delete-char-untabify>" #'picture-backward-clear-column
+ "<remap> <delete-backward-char>" #'picture-backward-clear-column
+ "<remap> <kill-line>" #'picture-clear-line
+ "<remap> <open-line>" #'picture-open-line
+ "<remap> <newline>" #'picture-newline
+ "<remap> <newline-and-indent>" #'picture-duplicate-line
+ "<remap> <next-line>" #'picture-move-down
+ "<remap> <previous-line>" #'picture-move-up
+ "<remap> <move-beginning-of-line>" #'picture-beginning-of-line
+ "<remap> <move-end-of-line>" #'picture-end-of-line
+ "<remap> <mouse-set-point>" #'picture-mouse-set-point
+ "C-c C-d" #'picture-delete-char
+ "TAB" #'picture-tab
+ "M-TAB" #'picture-tab-search
+ "C-c TAB" #'picture-set-tab-stops
+ "C-c C-k" #'picture-clear-rectangle
+ "C-c C-w" #'picture-clear-rectangle-to-register
+ "C-c C-y" #'picture-yank-rectangle
+ "C-c C-x" #'picture-yank-rectangle-from-register
+ "C-c C-r" #'picture-draw-rectangle
+ "C-c C-c" #'picture-mode-exit
+ "C-c C-f" #'picture-motion
+ "C-c C-b" #'picture-motion-reverse
+ "C-c <" #'picture-movement-left
+ "C-c >" #'picture-movement-right
+ "C-c ^" #'picture-movement-up
+ "C-c ." #'picture-movement-down
+ "C-c `" #'picture-movement-nw
+ "C-c '" #'picture-movement-ne
+ "C-c /" #'picture-movement-sw
+ "C-c \\" #'picture-movement-se
+ "C-c <left>" #'picture-movement-left
+ "C-c <right>" #'picture-movement-right
+ "C-c <up>" #'picture-movement-up
+ "C-c <down>" #'picture-movement-down
+ "C-c <home>" #'picture-movement-nw
+ "C-c <prior>" #'picture-movement-ne
+ "C-c <end>" #'picture-movement-sw
+ "C-c <next>" #'picture-movement-se)
(defcustom picture-mode-hook nil
"If non-nil, its value is called on entry to Picture mode.
diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el
index c7a9f20ea2c..f8c7af25005 100644
--- a/lisp/textmodes/remember.el
+++ b/lisp/textmodes/remember.el
@@ -548,13 +548,11 @@ If this is nil, then `diary-file' will be used instead."
;;; Internal Functions:
-(defvar remember-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-x\C-s" #'remember-finalize)
- (define-key map "\C-c\C-c" #'remember-finalize)
- (define-key map "\C-c\C-k" #'remember-destroy)
- map)
- "Keymap used in `remember-mode'.")
+(defvar-keymap remember-mode-map
+ :doc "Keymap used in `remember-mode'."
+ "C-x C-s" #'remember-finalize
+ "C-c C-c" #'remember-finalize
+ "C-c C-k" #'remember-destroy)
(define-derived-mode remember-mode text-mode "Remember"
"Major mode for output from \\[remember].
@@ -596,11 +594,9 @@ If this is nil, use `initial-major-mode'."
-(defvar remember-notes-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-c" #'remember-notes-save-and-bury-buffer)
- map)
- "Keymap used in `remember-notes-mode'.")
+(defvar-keymap remember-notes-mode-map
+ :doc "Keymap used in `remember-notes-mode'."
+ "C-c C-c" #'remember-notes-save-and-bury-buffer)
(define-minor-mode remember-notes-mode
"Minor mode for the `remember-notes' buffer.
diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el
index 7d691430ec6..7ce30cba8a4 100644
--- a/lisp/textmodes/sgml-mode.el
+++ b/lisp/textmodes/sgml-mode.el
@@ -268,7 +268,7 @@ Currently, only Latin-1 characters are supported.")
;; prefer tidy because (o)nsgmls is often built without --enable-http
;; which makes it next to useless
(cond ((executable-find "tidy")
- ;; tidy is available from http://tidy.sourceforge.net/
+ ;; tidy is available from https://tidy.sourceforge.net/
"tidy --gnu-emacs yes -utf8 -e -q")
((executable-find "nsgmls")
;; nsgmls is a free SGML parser in the SP suite available from
@@ -276,7 +276,7 @@ Currently, only Latin-1 characters are supported.")
"nsgmls -s")
((executable-find "onsgmls")
;; onsgmls is the community version of `nsgmls'
- ;; hosted on http://openjade.sourceforge.net/
+ ;; hosted on https://openjade.sourceforge.net/
"onsgmls -s")
(t "Install (o)nsgmls, tidy, or some other SGML validator, and set `sgml-validate-command'"))
"The command to validate an SGML document.
diff --git a/lisp/textmodes/string-edit.el b/lisp/textmodes/string-edit.el
index 53850674ac0..3270050ca4a 100644
--- a/lisp/textmodes/string-edit.el
+++ b/lisp/textmodes/string-edit.el
@@ -46,7 +46,9 @@ called with no parameters.
PROMPT will be inserted at the start of the buffer, but won't be
included in the resulting string. If PROMPT is nil, no help text
-will be inserted."
+will be inserted.
+
+Also see `read-string-from-buffer'."
(with-current-buffer (generate-new-buffer "*edit string*")
(when prompt
(let ((inhibit-read-only t))
@@ -88,7 +90,9 @@ The user finishes editing with \\<string-edit-mode-map>\\[string-edit-done], or
PROMPT will be inserted at the start of the buffer, but won't be
included in the resulting string. If nil, no prompt will be
-inserted in the buffer."
+inserted in the buffer.
+
+Also see `string-edit'."
(string-edit
prompt
string
@@ -115,9 +119,7 @@ This will kill the current buffer."
(interactive)
(goto-char (point-min))
;; Skip past the help text.
- (when-let ((match (text-property-search-forward
- 'string-edit--prompt nil t)))
- (goto-char (prop-match-beginning match)))
+ (text-property-search-forward 'string-edit--prompt)
(let ((string (buffer-substring (point) (point-max)))
(callback string-edit--success-callback))
(quit-window 'kill)
diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el
index fc06c4c0da1..964f94228b6 100644
--- a/lisp/textmodes/table.el
+++ b/lisp/textmodes/table.el
@@ -5221,16 +5221,15 @@ instead of the current buffer and returns the OBJECT."
"Point has entered a cell.
Refresh the menu bar."
;; Avoid calling point-motion-hooks recursively.
- (let ((inhibit-point-motion-hooks t))
- (force-mode-line-update)
- (pcase dir
- ('left
- (setq table-mode-indicator nil)
- (run-hooks 'table-point-left-cell-hook))
- ('entered
- (setq table-mode-indicator t)
- (table--warn-incompatibility)
- (run-hooks 'table-point-entered-cell-hook)))))
+ (force-mode-line-update)
+ (pcase dir
+ ('left
+ (setq table-mode-indicator nil)
+ (run-hooks 'table-point-left-cell-hook))
+ ('entered
+ (setq table-mode-indicator t)
+ (table--warn-incompatibility)
+ (run-hooks 'table-point-entered-cell-hook))))
(defun table--warn-incompatibility ()
"If called from interactive operation warn the know incompatibilities.
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index f624b604aac..ca0312d8fb0 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -980,24 +980,23 @@ Inherits `shell-mode-map' with a few additions.")
(save-excursion
(beginning-of-line)
(search-forward "%" search-end t))))))
- (when (and slash (not comment))
- (setq mode
- (if (looking-at
- (concat
- (regexp-opt '("documentstyle" "documentclass"
- "begin" "subsection" "section"
- "part" "chapter" "newcommand"
- "renewcommand" "RequirePackage")
- 'words)
- "\\|NeedsTeXFormat{LaTeX"))
- (if (and (looking-at
- "document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}")
- ;; SliTeX is almost never used any more nowadays.
- (tex-executable-exists-p slitex-run-command))
- #'slitex-mode
- #'latex-mode)
- #'plain-tex-mode))))
- mode))
+ (if (not (and slash (not comment)))
+ mode
+ (if (looking-at
+ (concat
+ (regexp-opt '("documentstyle" "documentclass"
+ "begin" "subsection" "section"
+ "part" "chapter" "newcommand"
+ "renewcommand" "RequirePackage")
+ 'words)
+ "\\|NeedsTeXFormat{LaTeX"))
+ (if (and (looking-at
+ "document\\(style\\|class\\)\\(\\[.*\\]\\)?{slides}")
+ ;; SliTeX is almost never used any more nowadays.
+ (tex-executable-exists-p slitex-run-command))
+ #'slitex-mode
+ #'latex-mode)
+ #'plain-tex-mode)))))
;; `tex-mode' plays two roles: it's the parent of several sub-modes
;; but it's also the function that chooses between those submodes.
@@ -1014,7 +1013,10 @@ such as if there are no commands in the file, the value of `tex-default-mode'
says which mode to use."
(tex-common-initialization))
-(advice-add 'tex-mode :around #'tex--redirect-to-submode)
+(advice-add 'tex-mode :around #'tex--redirect-to-submode
+ ;; Give it lower precedence than normal advice, so
+ ;; AUCTeX's advice takes precedence over it.
+ '((depth . 50)))
(defvar tex-mode--recursing nil)
(defun tex--redirect-to-submode (orig-fun)
"Redirect to one of the submodes when called directly."
@@ -1026,26 +1028,21 @@ says which mode to use."
;; We're called from one of the children already.
orig-fun
(setq tex-mode--recursing t)
- (tex--guess-mode)))))
+ (let ((mode (tex--guess-mode)))
+ ;; `tex--guess-mode' really tries to guess the *type* of file,
+ ;; so we still need to consult `major-mode-remap-alist'
+ ;; to see which mode to use for that type.
+ (alist-get mode major-mode-remap-alist mode))))))
;; The following three autoloaded aliases appear to conflict with
-;; AUCTeX. However, even though AUCTeX uses the mixed case variants
-;; for all mode relevant variables and hooks, the invocation function
-;; and setting of `major-mode' themselves need to be lowercase for
-;; AUCTeX to provide a fully functional user-level replacement. So
-;; these aliases should remain as they are, in particular since AUCTeX
-;; users are likely to use them.
-;; Note from Stef: I don't understand the above explanation, the only
-;; justification I can find to keep those confusing aliases is for those
-;; users who may have files annotated with -*- LaTeX -*- (e.g. because they
-;; received them from someone using AUCTeX).
-
-;;;###autoload
-(defalias 'TeX-mode #'tex-mode)
-;;;###autoload
-(defalias 'plain-TeX-mode #'plain-tex-mode)
-;;;###autoload
-(defalias 'LaTeX-mode #'latex-mode)
+;; AUCTeX. We keep those confusing aliases for those users who may
+;; have files annotated with -*- LaTeX -*- (e.g. because they received
+;; them from someone using AUCTeX).
+;; FIXME: Turn them into autoloads so that AUCTeX can override them
+;; with its own autoloads? Or maybe rely on `major-mode-remap-alist'?
+;;;###autoload (defalias 'TeX-mode #'tex-mode)
+;;;###autoload (defalias 'plain-TeX-mode #'plain-tex-mode)
+;;;###autoload (defalias 'LaTeX-mode #'latex-mode)
;;;###autoload
(define-derived-mode plain-tex-mode tex-mode "TeX"
@@ -1560,7 +1557,7 @@ a skeleton (see `skeleton-insert').")
'(if (and (boundp 'reftex-mode) reftex-mode) (reftex-label "table"))
\n _)
("figure" nil > _ \n "\\caption{" > (skeleton-read "Caption: ") "}" > \n
- '(if (and (boundp 'reftex-mode) reftex-mode) (reftex-label "table"))))
+ '(if (and (boundp 'reftex-mode) reftex-mode) (reftex-label "figure"))))
"Skeleton element to use for the body of particular environments.
Every element of the list has the form (NAME . SKEL-ELEM) where NAME is
the name of the environment and SKEL-ELEM is an element to use in
diff --git a/lisp/time.el b/lisp/time.el
index e7066cae7a5..247d715ab66 100644
--- a/lisp/time.el
+++ b/lisp/time.el
@@ -528,7 +528,15 @@ If the value is t instead of an alist, use the value of
(defvar-keymap world-clock-mode-map
"n" #'next-line
- "p" #'previous-line)
+ "p" #'previous-line
+ "w" #'world-clock-copy-time-as-kill)
+
+(defun world-clock-copy-time-as-kill ()
+ "Copy current line into the kill ring."
+ (interactive nil world-clock-mode)
+ (when-let ((str (buffer-substring-no-properties (pos-bol) (pos-eol))))
+ (kill-new str)
+ (message str)))
(define-derived-mode world-clock-mode special-mode "World clock"
"Major mode for buffer that displays times in various time zones.
diff --git a/lisp/url/url-file.el b/lisp/url/url-file.el
index a72b2e67a6a..6258e999c1d 100644
--- a/lisp/url/url-file.el
+++ b/lisp/url/url-file.el
@@ -150,7 +150,6 @@ it up to them."
(uncompressed-filename nil)
(content-type nil)
(content-encoding nil)
- (coding-system-for-read 'binary)
(filename (url-file-build-filename url)))
(or filename (error "File does not exist: %s" (url-recreate-url url)))
;; Need to figure out the content-type from the real extension,
diff --git a/lisp/url/url-handlers.el b/lisp/url/url-handlers.el
index 74f77cd2383..cb115fceb23 100644
--- a/lisp/url/url-handlers.el
+++ b/lisp/url/url-handlers.el
@@ -302,11 +302,13 @@ accessible."
filename))
(put 'file-local-copy 'url-file-handlers #'url-file-local-copy)
-(defun url-insert (buffer &optional beg end)
+(defun url-insert (buffer &optional beg end inhibit-decode)
"Insert the body of a URL object.
BUFFER should be a complete URL buffer as returned by `url-retrieve'.
If the headers specify a coding-system (and current buffer is multibyte),
-it is applied to the body before it is inserted.
+it is applied to the body before it is inserted. If INHIBIT-DECODE is
+non-nil, don't do any coding system decoding even in multibyte buffers.
+
Returns a list of the form (SIZE CHARSET), where SIZE is the size in bytes
of the inserted text and CHARSET is the charset that was specified in the
header, or nil if none was found.
@@ -318,7 +320,8 @@ They count bytes from the beginning of the body."
(buffer-substring (+ (point-min) beg)
(if end (+ (point-min) end) (point-max)))
(buffer-string))))
- (charset (if enable-multibyte-characters
+ (charset (if (and enable-multibyte-characters
+ (not inhibit-decode))
(mail-content-type-get (mm-handle-type handle)
'charset))))
(mm-destroy-parts handle)
@@ -362,6 +365,16 @@ if it had been inserted from a file named URL."
(url-insert-buffer-contents buffer url visit beg end replace)))
(put 'insert-file-contents 'url-file-handlers #'url-insert-file-contents)
+;;;###autoload
+(defun url-insert-file-contents-literally (url)
+ "Insert the data retrieved from URL literally in the current buffer."
+ (let ((buffer (url-retrieve-synchronously url)))
+ (unless buffer
+ (signal 'file-error (list url "No Data")))
+ (url-insert buffer nil nil t)
+ (kill-buffer buffer)
+ nil))
+
(defun url-file-name-completion (url _directory &optional _predicate)
;; Even if it's not implemented, it's not an error to ask for completion,
;; in case it's available (bug#14806).
diff --git a/lisp/url/url.el b/lisp/url/url.el
index d08ff04eda9..b4ece5faeb2 100644
--- a/lisp/url/url.el
+++ b/lisp/url/url.el
@@ -280,7 +280,9 @@ how long to wait for a response before giving up."
;; Querying over consumer internet in the US takes 100
;; ms, so split the difference.
(accept-process-output nil 0.05)))
- (unless (eq data-buffer proc-buffer)
+ ;; Kill the process buffer on redirects.
+ (when (and data-buffer
+ (not (eq data-buffer proc-buffer)))
(let (kill-buffer-query-functions)
(kill-buffer proc-buffer)))))
data-buffer))
diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el
index d617d5aebb2..e3c0e2ca06d 100644
--- a/lisp/vc/add-log.el
+++ b/lisp/vc/add-log.el
@@ -806,7 +806,7 @@ if it were to exist."
(defun add-log-find-changelog-buffer (changelog-file-name)
"Find a ChangeLog buffer for CHANGELOG-FILE-NAME.
-Respect `add-log-use-pseudo-changelog', which see."
+Respect `add-log--pseudo-changelog-buffer-name', which see."
(if (or (file-exists-p changelog-file-name)
(not add-log-dont-create-changelog-file))
(find-file-noselect changelog-file-name)
diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el
index 52906163024..4624ada4179 100644
--- a/lisp/vc/log-edit.el
+++ b/lisp/vc/log-edit.el
@@ -325,6 +325,11 @@ automatically."
(defface log-edit-summary '((t :inherit font-lock-function-name-face))
"Face for the summary in `log-edit-mode' buffers.")
+(defface log-edit-headers-separator
+ '((t :height 0.1 :inverse-video t :extend t))
+ "Face for the separator line in `log-edit-mode' buffers."
+ :version "29.1")
+
(defface log-edit-header '((t :inherit font-lock-keyword-face))
"Face for the headers in `log-edit-mode' buffers.")
@@ -393,7 +398,7 @@ The first subexpression is the actual text of the field.")
nil lax))
("^\n"
(progn (goto-char (match-end 0)) (1+ (match-end 0))) nil
- (0 '(face (:height 0.1 :inverse-video t :extend t)
+ (0 '(face log-edit-headers-separator
display-line-numbers-disable t rear-nonsticky t))))
(log-edit--match-first-line (0 'log-edit-summary))))
diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el
index 415b1564eda..7a710386fee 100644
--- a/lisp/vc/log-view.el
+++ b/lisp/vc/log-view.el
@@ -359,6 +359,7 @@ log entries."
(overlay-put ov 'log-view-self ov)
(overlay-put ov 'log-view-marked (nth 1 entry))))))))
+;;;###autoload
(defun log-view-get-marked ()
"Return the list of tags for the marked log entries."
(save-excursion
diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el
index f6b17d4ce09..6f77f995554 100644
--- a/lisp/vc/vc-bzr.el
+++ b/lisp/vc/vc-bzr.el
@@ -339,7 +339,7 @@ in the repository root directory of FILE."
"Value of `compilation-error-regexp-alist' in *vc-bzr* buffers.")
;; To be called via vc-pull from vc.el, which requires vc-dispatcher.
-(declare-function vc-exec-after "vc-dispatcher" (code))
+(declare-function vc-exec-after "vc-dispatcher" (code &optional success))
(declare-function vc-set-async-update "vc-dispatcher" (process-buffer))
(declare-function vc-compilation-mode "vc-dispatcher" (backend))
@@ -1324,6 +1324,20 @@ stream. Standard error output is discarded."
(match-string 1)
(error "Cannot determine Bzr repository URL")))))
+(defun vc-bzr-prepare-patch (rev)
+ (with-current-buffer (generate-new-buffer " *vc-bzr-prepare-patch*")
+ (vc-bzr-command
+ "send" t 0 '()
+ "--revision" (concat (vc-bzr-previous-revision nil rev) ".." rev)
+ "--output" "-")
+ (let (subject)
+ ;; Extract the subject line
+ (goto-char (point-min))
+ (search-forward-regexp "^[^#].*")
+ (setq subject (match-string 0))
+ ;; Return the extracted data
+ (list :subject subject :buffer (current-buffer)))))
+
(provide 'vc-bzr)
;;; vc-bzr.el ends here
diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el
index 52cc42791fa..2dd3d416ac7 100644
--- a/lisp/vc/vc-cvs.el
+++ b/lisp/vc/vc-cvs.el
@@ -545,7 +545,7 @@ Will fail unless you have administrative privileges on the repo."
;;;
;; Follows vc-cvs-command, which uses vc-do-command from vc-dispatcher.
-(declare-function vc-exec-after "vc-dispatcher" (code))
+(declare-function vc-exec-after "vc-dispatcher" (code &optional success))
(defun vc-cvs-print-log (files buffer &optional _shortlog _start-revision limit)
"Print commit log associated with FILES into specified BUFFER.
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index b4568727ea0..037de415e62 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -266,7 +266,7 @@ See `run-hooks'."
:enable (vc-find-backend-function vc-dir-backend 'push)
:help "Push the current branch's changes"))
(define-key map [update]
- '(menu-item "Update to Latest Version" vc-update
+ '(menu-item "Update to Latest Version" vc-pull
:help "Update the current fileset's files to their tip revisions"))
(define-key map [revert]
'(menu-item "Revert to Base Version" vc-revert
@@ -306,8 +306,8 @@ See `run-hooks'."
(define-key map "=" #'vc-diff) ;; C-x v =
(define-key map "D" #'vc-root-diff) ;; C-x v D
(define-key map "i" #'vc-register) ;; C-x v i
- (define-key map "+" #'vc-update) ;; C-x v +
- ;; I'd prefer some kind of symmetry with vc-update:
+ (define-key map "+" #'vc-pull) ;; C-x v +
+ ;; I'd prefer some kind of symmetry with vc-pull:
(define-key map "P" #'vc-push) ;; C-x v P
(define-key map "l" #'vc-print-log) ;; C-x v l
(define-key map "L" #'vc-print-root-log) ;; C-x v L
diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el
index 36a6f27891b..dc3ed526506 100644
--- a/lisp/vc/vc-dispatcher.el
+++ b/lisp/vc/vc-dispatcher.el
@@ -109,6 +109,8 @@
;; TODO:
;; - log buffers need font-locking.
+(eval-when-compile (require 'cl-lib))
+
;; General customization
(defcustom vc-logentry-check-hook nil
@@ -194,7 +196,7 @@ Another is that undo information is not kept."
(defvar vc-sentinel-movepoint) ;Dynamically scoped.
-(defun vc--process-sentinel (p code)
+(defun vc--process-sentinel (p code &optional success)
(let ((buf (process-buffer p)))
;; Impatient users sometime kill "slow" buffers; check liveness
;; to avoid "error in process sentinel: Selecting deleted buffer".
@@ -215,7 +217,7 @@ Another is that undo information is not kept."
;; each sentinel read&set process-mark, but since `cmd' needs
;; to work both for async and sync processes, this would be
;; difficult to achieve.
- (vc-exec-after code)
+ (vc-exec-after code success)
(move-marker m (point)))
;; But sometimes the sentinels really want to move point.
(when vc-sentinel-movepoint
@@ -232,11 +234,14 @@ Another is that undo information is not kept."
'help-echo
"A command is in progress in this buffer"))))
-(defun vc-exec-after (code)
+(defun vc-exec-after (code &optional success)
"Eval CODE when the current buffer's process is done.
If the current buffer has no process, just evaluate CODE.
Else, add CODE to the process' sentinel.
-CODE should be a function of no arguments."
+CODE should be a function of no arguments.
+
+If SUCCESS, it should be a process object. Only run CODE if the
+SUCCESS process has a zero exit code."
(let ((proc (get-buffer-process (current-buffer))))
(cond
;; If there's no background process, just execute the code.
@@ -247,13 +252,15 @@ CODE should be a function of no arguments."
((or (null proc) (eq (process-status proc) 'exit))
;; Make sure we've read the process's output before going further.
(when proc (accept-process-output proc))
- (if (functionp code) (funcall code) (eval code t)))
+ (when (or (not success)
+ (zerop (process-exit-status success)))
+ (if (functionp code) (funcall code) (eval code t))))
;; If a process is running, add CODE to the sentinel
((eq (process-status proc) 'run)
(vc-set-mode-line-busy-indicator)
(letrec ((fun (lambda (p _msg)
(remove-function (process-sentinel p) fun)
- (vc--process-sentinel p code))))
+ (vc--process-sentinel p code success))))
(add-function :after (process-sentinel proc) fun)))
(t (error "Unexpected process state"))))
nil)
@@ -262,6 +269,13 @@ CODE should be a function of no arguments."
(declare (indent 0) (debug (def-body)))
`(vc-exec-after (lambda () ,@body)))
+(defvar vc-filter-command-function #'list
+ "Function called to transform VC commands before execution.
+The function is called inside the buffer in which the command
+will be run and is passed the COMMAND, FILE-OR-LIST and FLAGS
+arguments to `vc-do-command'. It should return a list of three
+elements, the new values for these arguments.")
+
(defvar vc-post-command-functions nil
"Hook run at the end of `vc-do-command'.
Each function is called inside the buffer in which the command was run
@@ -282,6 +296,23 @@ the man pages for \"torsocks\" for more details about Tor."
:version "27.1"
:group 'vc)
+(defun vc-user-edit-command (command file-or-list flags)
+ "Prompt the user to edit VC command COMMAND and FLAGS.
+Intended to be used as the value of `vc-filter-command-function'."
+ (let* ((files-separator-p (string= "--" (car (last flags))))
+ (edited (split-string-and-unquote
+ (read-shell-command
+ (format "Edit VC command & arguments%s: "
+ (if file-or-list
+ " (files list to be appended)"
+ ""))
+ (combine-and-quote-strings
+ (cons command (remq nil (if files-separator-p
+ (butlast flags)
+ flags))))))))
+ (list (car edited) file-or-list
+ (nconc (cdr edited) (and files-separator-p '("--"))))))
+
;;;###autoload
(defun vc-do-command (buffer okstatus command file-or-list &rest flags)
"Execute a slave command, notifying user and checking for errors.
@@ -296,117 +327,142 @@ FILE-OR-LIST is the name of a working file; it may be a list of
files or be nil (to execute commands that don't expect a file
name or set of files). If an optional list of FLAGS is present,
that is inserted into the command line before the filename.
+
Return the return value of the slave command in the synchronous
case, and the process object in the asynchronous case."
- ;; FIXME: file-relative-name can return a bogus result because
- ;; it doesn't look at the actual file-system to see if symlinks
- ;; come into play.
- (let* ((files
- (mapcar (lambda (f) (file-relative-name (expand-file-name f)))
- (if (listp file-or-list) file-or-list (list file-or-list))))
- ;; Keep entire commands in *Messages* but avoid resizing the
- ;; echo area. Messages in this function are formatted in
- ;; a such way that the important parts are at the beginning,
- ;; due to potential truncation of long messages.
- (message-truncate-lines t)
- (full-command
- (concat (if vc-tor "torsocks " "")
- (if (string= (substring command -1) "\n")
- (substring command 0 -1)
- command)
- " " (vc-delistify flags)
- " " (vc-delistify files)))
- (vc-inhibit-message
- (or (eq vc-command-messages 'log)
- (eq (selected-window) (active-minibuffer-window)))))
+ (let (;; Keep entire commands in *Messages* but avoid resizing the
+ ;; echo area. Messages in this function are formatted in
+ ;; a such way that the important parts are at the beginning,
+ ;; due to potential truncation of long messages.
+ (message-truncate-lines t)
+ (vc-inhibit-message
+ (or (eq vc-command-messages 'log)
+ (eq (selected-window) (active-minibuffer-window)))))
(save-current-buffer
(unless (or (eq buffer t)
(and (stringp buffer)
(string= (buffer-name) buffer))
(eq buffer (current-buffer)))
- (vc-setup-buffer buffer))
- ;; If there's some previous async process still running, just kill it.
- (let ((squeezed (remq nil flags))
- (inhibit-read-only t)
- (status 0))
- (when files
- (setq squeezed (nconc squeezed files)))
- (let (;; Since some functions need to parse the output
- ;; from external commands, set LC_MESSAGES to C.
- (process-environment (cons "LC_MESSAGES=C" process-environment))
- (w32-quote-process-args t))
- (if (eq okstatus 'async)
- ;; Run asynchronously.
- (let ((proc
- (let ((process-connection-type nil))
- (apply #'start-file-process command (current-buffer)
- command squeezed))))
- (when vc-command-messages
- (let ((inhibit-message vc-inhibit-message))
- (message "Running in background: %s" full-command)))
- ;; Get rid of the default message insertion, in case we don't
- ;; set a sentinel explicitly.
- (set-process-sentinel proc #'ignore)
- (set-process-filter proc #'vc-process-filter)
- (setq status proc)
- (when vc-command-messages
- (vc-run-delayed
- (let ((message-truncate-lines t)
- (inhibit-message vc-inhibit-message))
- (message "Done in background: %s" full-command)))))
- ;; Run synchronously
- (when vc-command-messages
- (let ((inhibit-message vc-inhibit-message))
- (message "Running in foreground: %s" full-command)))
- (let ((buffer-undo-list t))
- (setq status (apply #'process-file command nil t nil squeezed)))
- (when (and (not (eq t okstatus))
- (or (not (integerp status))
- (and okstatus (< okstatus status))))
- (unless (eq ?\s (aref (buffer-name (current-buffer)) 0))
- (pop-to-buffer (current-buffer))
- (goto-char (point-min))
- (shrink-window-if-larger-than-buffer))
- (error "Failed (%s): %s"
- (if (integerp status) (format "status %d" status) status)
- full-command))
- (when vc-command-messages
- (let ((inhibit-message vc-inhibit-message))
- (message "Done (status=%d): %s" status full-command)))))
- (vc-run-delayed
- (run-hook-with-args 'vc-post-command-functions
- command file-or-list flags))
- status))))
+ (vc-setup-buffer buffer))
+ (cl-destructuring-bind (command file-or-list flags)
+ (funcall vc-filter-command-function command file-or-list flags)
+ (when vc-tor
+ (push command flags)
+ (setq command "torsocks"))
+ (let* (;; FIXME: file-relative-name can return a bogus result
+ ;; because it doesn't look at the actual file-system to
+ ;; see if symlinks come into play.
+ (files
+ (mapcar (lambda (f)
+ (file-relative-name (expand-file-name f)))
+ (if (listp file-or-list)
+ file-or-list
+ (list file-or-list))))
+ (full-command
+ (concat (if (string= (substring command -1) "\n")
+ (substring command 0 -1)
+ command)
+ " " (vc-delistify flags)
+ " " (vc-delistify files)))
+ (squeezed (remq nil flags))
+ (inhibit-read-only t)
+ (status 0))
+ ;; If there's some previous async process still running,
+ ;; just kill it.
+ (when files
+ (setq squeezed (nconc squeezed files)))
+ (let (;; Since some functions need to parse the output
+ ;; from external commands, set LC_MESSAGES to C.
+ (process-environment
+ (cons "LC_MESSAGES=C" process-environment))
+ (w32-quote-process-args t))
+ (if (eq okstatus 'async)
+ ;; Run asynchronously.
+ (let ((proc
+ (let ((process-connection-type nil))
+ (apply #'start-file-process command
+ (current-buffer) command squeezed))))
+ (when vc-command-messages
+ (let ((inhibit-message vc-inhibit-message))
+ (message "Running in background: %s"
+ full-command)))
+ ;; Get rid of the default message insertion, in case
+ ;; we don't set a sentinel explicitly.
+ (set-process-sentinel proc #'ignore)
+ (set-process-filter proc #'vc-process-filter)
+ (setq status proc)
+ (when vc-command-messages
+ (vc-run-delayed
+ (let ((message-truncate-lines t)
+ (inhibit-message vc-inhibit-message))
+ (message "Done in background: %s"
+ full-command)))))
+ ;; Run synchronously
+ (when vc-command-messages
+ (let ((inhibit-message vc-inhibit-message))
+ (message "Running in foreground: %s" full-command)))
+ (let ((buffer-undo-list t))
+ (setq status (apply #'process-file
+ command nil t nil squeezed)))
+ (when (and (not (eq t okstatus))
+ (or (not (integerp status))
+ (and okstatus (< okstatus status))))
+ (unless (eq ?\s (aref (buffer-name (current-buffer)) 0))
+ (pop-to-buffer (current-buffer))
+ (goto-char (point-min))
+ (shrink-window-if-larger-than-buffer))
+ (error "Failed (%s): %s"
+ (if (integerp status)
+ (format "status %d" status)
+ status)
+ full-command))
+ (when vc-command-messages
+ (let ((inhibit-message vc-inhibit-message))
+ (message "Done (status=%d): %s"
+ status full-command)))))
+ (vc-run-delayed
+ (run-hook-with-args 'vc-post-command-functions
+ command file-or-list flags))
+ status)))))
+
+(defvar vc--inhibit-async-window nil)
(defun vc-do-async-command (buffer root command &rest args)
"Run COMMAND asynchronously with ARGS, displaying the result.
Send the output to BUFFER, which should be a buffer or the name
of a buffer, which is created.
ROOT should be the directory in which the command should be run.
+The process object is returned.
Display the buffer in some window, but don't select it."
- (let* ((dir default-directory)
- (inhibit-read-only t)
- window new-window-start)
+ (let ((dir default-directory)
+ (inhibit-read-only t)
+ new-window-start proc)
(setq buffer (get-buffer-create buffer))
(if (get-buffer-process buffer)
(error "Another VC action on %s is running" root))
(with-current-buffer buffer
(setq default-directory root)
- (goto-char (point-max))
- (unless (eq (point) (point-min))
- (insert " \n"))
- (setq new-window-start (point))
- (insert "Running \"" command)
- (dolist (arg args)
- (insert " " arg))
- (insert "\"...\n")
- ;; Run in the original working directory.
- (let ((default-directory dir))
- (apply #'vc-do-command t 'async command nil args)))
- (setq window (display-buffer buffer))
- (if window
- (set-window-start window new-window-start))
- buffer))
+ (let* (;; Run in the original working directory.
+ (default-directory dir)
+ (orig-fun vc-filter-command-function)
+ (vc-filter-command-function
+ (lambda (&rest args)
+ (cl-destructuring-bind (&whole args cmd _ flags)
+ (apply orig-fun args)
+ (goto-char (point-max))
+ (unless (eq (point) (point-min))
+ (insert " \n"))
+ (setq new-window-start (point))
+ (insert "Running \"" cmd)
+ (dolist (flag flags)
+ (insert " " flag))
+ (insert "\"...\n")
+ args))))
+ (setq proc (apply #'vc-do-command t 'async command nil args))))
+ (unless vc--inhibit-async-window
+ (when-let ((window (display-buffer buffer)))
+ (set-window-start window new-window-start)))
+ proc))
(defvar compilation-error-regexp-alist)
@@ -704,7 +760,11 @@ PATCH-STRING is a patch to check in."
(erase-buffer)
(when (stringp comment) (insert comment)))
(if (or (not comment) initial-contents)
- (message "%s Type C-c C-c when done" msg)
+ (message (substitute-command-keys
+ (if (eq major-mode 'log-edit-mode)
+ "%s Type \\[log-edit-done] when done"
+ "%s Type \\`C-c C-c' when done"))
+ msg)
(vc-finish-logentry (eq comment t)))))
;; vc-finish-logentry is typically called from a log-edit buffer (see
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 8d8ea33f8b3..3c6afec0378 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -95,6 +95,7 @@
;; - find-file-hook () OK
;; - conflicted-files OK
;; - repository-url (file-or-dir) OK
+;; - prepare-patch (rev) OK
;;; Code:
@@ -119,14 +120,6 @@ If nil, use the value of `vc-diff-switches'. If t, use no switches."
(repeat :tag "Argument List" :value ("") string))
:version "23.1")
-;;;###autoload
-(defun vc-git-annotate-switches-safe-p (switches)
- "Check if local value of `vc-git-annotate-switches' is safe.
-Currently only \"-w\" (ignore whitespace) is considered safe, but
-this list might be extended in the future."
- ;; TODO: Probably most options are perfectly safe.
- (equal switches "-w"))
-
(defcustom vc-git-annotate-switches nil
"String or list of strings specifying switches for Git blame under VC.
If nil, use the value of `vc-annotate-switches'. If t, use no switches."
@@ -135,7 +128,12 @@ If nil, use the value of `vc-annotate-switches'. If t, use no switches."
(string :tag "Argument String")
(repeat :tag "Argument List" :value ("") string))
:version "25.1")
-;;;###autoload(put 'vc-git-annotate-switches 'safe-local-variable #'vc-git-annotate-switches-safe-p)
+
+;; Check if local value of `vc-git-annotate-switches' is safe.
+;; Currently only "-w" (ignore whitespace) is considered safe, but
+;; this list might be extended in the future (probably most options
+;; are perfectly safe.)
+;;;###autoload(put 'vc-git-annotate-switches 'safe-local-variable (lambda (switches) (equal switches "-w")))
(defcustom vc-git-log-switches nil
"String or list of strings specifying switches for Git log under VC."
@@ -375,8 +373,9 @@ in the order given by `git status'."
(defun vc-git-working-revision (_file)
"Git-specific version of `vc-working-revision'."
- (let (process-file-side-effects)
- (vc-git--rev-parse "HEAD")))
+ (let* ((process-file-side-effects nil)
+ (commit (vc-git--rev-parse "HEAD" t)))
+ (or (vc-git-symbolic-commit commit) commit)))
(defun vc-git--symbolic-ref (file)
(or
@@ -627,7 +626,7 @@ or an empty string if none."
;; Follows vc-git-command (or vc-do-async-command), which uses vc-do-command
;; from vc-dispatcher.
-(declare-function vc-exec-after "vc-dispatcher" (code))
+(declare-function vc-exec-after "vc-dispatcher" (code &optional success))
;; Follows vc-exec-after.
(declare-function vc-set-async-update "vc-dispatcher" (process-buffer))
@@ -1018,7 +1017,31 @@ It is based on `log-edit-mode', and has Git-specific extensions."
(make-nearby-temp-file "git-msg")))))
(when vc-git-patch-string
(unless (zerop (vc-git-command nil t nil "diff" "--cached" "--quiet"))
- (user-error "Index not empty"))
+ ;; Check that all staged changes also exist in the patch.
+ ;; This is needed to allow adding/removing files that are
+ ;; currently staged to the index. So remove the whole file diff
+ ;; from the patch because commit will take it from the index.
+ (with-temp-buffer
+ (vc-git-command (current-buffer) t nil "diff" "--cached")
+ (goto-char (point-min))
+ (let ((pos (point)) file-diff file-beg)
+ (while (not (eobp))
+ (forward-line 1) ; skip current "diff --git" line
+ (search-forward "diff --git" nil 'move)
+ (move-beginning-of-line 1)
+ (setq file-diff (buffer-substring pos (point)))
+ (if (and (setq file-beg (string-search
+ file-diff vc-git-patch-string))
+ ;; Check that file diff ends with an empty string
+ ;; or the beginning of the next file diff.
+ (string-match-p "\\`\\'\\|\\`diff --git"
+ (substring
+ vc-git-patch-string
+ (+ file-beg (length file-diff)))))
+ (setq vc-git-patch-string
+ (string-replace file-diff "" vc-git-patch-string))
+ (user-error "Index not empty"))
+ (setq pos (point))))))
(let ((patch-file (make-temp-file "git-patch")))
(with-temp-file patch-file
(insert vc-git-patch-string))
@@ -1096,31 +1119,37 @@ It is based on `log-edit-mode', and has Git-specific extensions."
(defun vc-git--pushpull (command prompt extra-args)
"Run COMMAND (a string; either push or pull) on the current Git branch.
If PROMPT is non-nil, prompt for the Git command to run."
+ (require 'vc-dispatcher)
(let* ((root (vc-git-root default-directory))
(buffer (format "*vc-git : %s*" (expand-file-name root)))
- (git-program vc-git-program)
- args)
- ;; If necessary, prompt for the exact command.
- ;; TODO if pushing, prompt if no default push location - cf bzr.
- (when prompt
- (setq args (split-string
- (read-shell-command
- (format "Git %s command: " command)
- (format "%s %s" git-program command)
- 'vc-git-history)
- " " t))
- (setq git-program (car args)
- command (cadr args)
- args (cddr args)))
- (setq args (nconc args extra-args))
- (require 'vc-dispatcher)
- (apply #'vc-do-async-command buffer root git-program command args)
+ (git-program vc-git-program)
+ ;; TODO if pushing, prompt if no default push location - cf bzr.
+ (vc-filter-command-function
+ (if prompt
+ (lambda (&rest args)
+ (cl-destructuring-bind (&whole args git _ flags)
+ (apply #'vc-user-edit-command args)
+ (setq git-program git
+ command (car flags)
+ extra-args (cdr flags))
+ args))
+ vc-filter-command-function))
+ (proc (apply #'vc-do-async-command
+ buffer root git-program command extra-args)))
+ ;; "git pull" includes progress output that uses ^M to move point
+ ;; to the beginning of the line. Just translate these to newlines
+ ;; (but don't do anything with the CRLF sequence).
+ (add-function :around (process-filter proc)
+ (lambda (filter process string)
+ (funcall filter process
+ (replace-regexp-in-string "\r\\(\\'\\|[^\n]\\)"
+ "\n\\1" string))))
(with-current-buffer buffer
(vc-run-delayed
(vc-compilation-mode 'git)
(setq-local compile-command
(concat git-program " " command " "
- (mapconcat #'identity args " ")))
+ (mapconcat #'identity extra-args " ")))
(setq-local compilation-directory root)
;; Either set `compilation-buffer-name-function' locally to nil
;; or use `compilation-arguments' to set `name-function'.
@@ -1129,7 +1158,8 @@ If PROMPT is non-nil, prompt for the Git command to run."
(list compile-command nil
(lambda (_name-of-mode) buffer)
nil))))
- (vc-set-async-update buffer)))
+ (vc-set-async-update buffer)
+ proc))
(defun vc-git-pull (prompt)
"Pull changes into the current Git branch.
@@ -1143,6 +1173,25 @@ Normally, this runs \"git push\". If PROMPT is non-nil, prompt
for the Git command to run."
(vc-git--pushpull "push" prompt nil))
+(defun vc-git-pull-and-push (prompt)
+ "Pull changes into the current Git branch, and then push.
+The push will only be performed if the pull was successful.
+
+Normally, this runs \"git pull\". If PROMPT is non-nil, prompt
+for the Git command to run."
+ (let ((proc (vc-git--pushpull "pull" prompt '("--stat"))))
+ (when (process-buffer proc)
+ (with-current-buffer (process-buffer proc)
+ (if (and (eq (process-status proc) 'exit)
+ (zerop (process-exit-status proc)))
+ (let ((vc--inhibit-async-window t))
+ (vc-git-push nil))
+ (vc-exec-after
+ (lambda ()
+ (let ((vc--inhibit-async-window t))
+ (vc-git-push nil)))
+ proc))))))
+
(defun vc-git-merge-branch ()
"Merge changes into the current Git branch.
This prompts for a branch to merge from."
@@ -1299,7 +1348,12 @@ If LIMIT is a revision string, use it as an end-revision."
(defun vc-git-log-incoming (buffer remote-location)
(vc-setup-buffer buffer)
- (vc-git-command nil 0 nil "fetch")
+ (vc-git-command nil 0 nil "fetch"
+ (unless (string= remote-location "")
+ ;; `remote-location' is in format "repository/branch",
+ ;; so remove everything except a repository name.
+ (replace-regexp-in-string
+ "/.*" "" remote-location)))
(vc-git-command
buffer 'async nil
"log"
@@ -1582,7 +1636,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
(start-point (when branchp (vc-read-revision
(format-prompt "Start point"
(car (vc-git-branches)))
- (list dir) 'Git))))
+ (list dir) 'Git (car (vc-git-branches))))))
(and (or (zerop (vc-git-command nil t nil "update-index" "--refresh"))
(y-or-n-p "Modified files exist. Proceed? ")
(user-error (format "Can't create %s with modified files"
@@ -1621,11 +1675,15 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
;; does not (and cannot) quote.
(vc-git--rev-parse (concat rev "~1"))))
-(defun vc-git--rev-parse (rev)
+(defun vc-git--rev-parse (rev &optional short)
(with-temp-buffer
(and
- (vc-git--out-ok "rev-parse" rev)
- (buffer-substring-no-properties (point-min) (+ (point-min) 40)))))
+ (if short
+ (vc-git--out-ok "rev-parse" "--short" rev)
+ (vc-git--out-ok "rev-parse" rev))
+ (string-trim-right
+ (buffer-substring-no-properties (point-min) (min (+ (point-min) 40)
+ (point-max)))))))
(defun vc-git-next-revision (file rev)
"Git-specific version of `vc-next-revision'."
@@ -1690,6 +1748,29 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"."
(defun vc-git-root (file)
(vc-find-root file ".git"))
+(defun vc-git-prepare-patch (rev)
+ (with-current-buffer (generate-new-buffer " *vc-git-prepare-patch*")
+ (vc-git-command
+ t 0 '() "format-patch"
+ "--no-numbered" "--stdout"
+ ;; From gitrevisions(7): ^<n> means the <n>th parent
+ ;; (i.e. <rev>^ is equivalent to <rev>^1). As a
+ ;; special rule, <rev>^0 means the commit itself and
+ ;; is used when <rev> is the object name of a tag
+ ;; object that refers to a commit object.
+ (concat rev "^.." rev))
+ (let (subject)
+ ;; Extract the subject line
+ (goto-char (point-min))
+ (search-forward-regexp "^Subject: \\(.+\\)")
+ (setq subject (match-string 1))
+ ;; Jump to the beginning for the patch
+ (search-forward-regexp "\n\n")
+ ;; Return the extracted data
+ (list :subject subject
+ :buffer (current-buffer)
+ :body-start (point)))))
+
;; grep-compute-defaults autoloads grep.
(declare-function grep-read-regexp "grep" ())
(declare-function grep-read-files "grep" (regexp))
@@ -1949,19 +2030,23 @@ FILE can be nil."
(setq ok nil))))))
(and ok str)))
-(defun vc-git-symbolic-commit (commit)
- "Translate COMMIT string into symbolic form.
-Returns nil if not possible."
+(defun vc-git-symbolic-commit (commit &optional force)
+ "Translate revision string of COMMIT to a symbolic form.
+If the optional argument FORCE is non-nil, the returned value is
+allowed to include revision specifications like \"master~8\"
+\(the 8th parent of the commit currently pointed to by the master
+branch), otherwise such revision specifications are rejected, and
+the function returns nil."
(and commit
- (let ((name (with-temp-buffer
- (and
- (vc-git--out-ok "name-rev" "--name-only" commit)
- (goto-char (point-min))
- (= (forward-line 2) 1)
- (bolp)
- (buffer-substring-no-properties (point-min)
- (1- (point-max)))))))
- (and name (not (string= name "undefined")) name))))
+ (with-temp-buffer
+ (and
+ (vc-git--out-ok "name-rev" "--no-undefined" "--name-only" commit)
+ (goto-char (point-min))
+ (or force (not (looking-at "^.*[~^].*$" t)))
+ (= (forward-line 2) 1)
+ (bolp)
+ (buffer-substring-no-properties (point-min)
+ (1- (point-max)))))))
(defvar-keymap vc-dir-git-mode-map
"z c" #'vc-git-stash
diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el
index f4a44df3c29..2eebe2d5434 100644
--- a/lisp/vc/vc-hg.el
+++ b/lisp/vc/vc-hg.el
@@ -80,6 +80,7 @@
;; - delete-file (file) TEST IT
;; - rename-file (old new) OK
;; - find-file-hook () added for bug#10709
+;; - prepare-patch (rev) OK
;; 2) Implement Stefan Monnier's advice:
;; vc-hg-registered and vc-hg-state
@@ -1345,7 +1346,7 @@ REV is the revision to check out into WORKFILE."
;; Follows vc-hg-command (or vc-do-async-command), which uses vc-do-command
;; from vc-dispatcher.
-(declare-function vc-exec-after "vc-dispatcher" (code))
+(declare-function vc-exec-after "vc-dispatcher" (code &optional success))
;; Follows vc-exec-after.
(declare-function vc-set-async-update "vc-dispatcher" (process-buffer))
@@ -1507,6 +1508,17 @@ This runs the command \"hg merge\"."
(with-current-buffer buffer (vc-run-delayed (vc-compilation-mode 'hg)))
(vc-set-async-update buffer)))
+(defun vc-hg-prepare-patch (rev)
+ (with-current-buffer (generate-new-buffer " *vc-hg-prepare-patch*")
+ (vc-hg-command t 0 '() "export" "--rev" rev)
+ (let (subject)
+ ;; Extract the subject line
+ (goto-char (point-min))
+ (search-forward-regexp "^[^#].*")
+ (setq subject (match-string 0))
+ ;; Return the extracted data
+ (list :subject subject :buffer (current-buffer)))))
+
;;; Internal functions
(defun vc-hg-command (buffer okstatus file-or-list &rest flags)
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index 7f0d9e4d862..6ad26cfe674 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -882,7 +882,8 @@ In the latter case, VC mode is deactivated for this buffer."
"=" #'vc-diff
"D" #'vc-root-diff
"~" #'vc-revision-other-window
- "x" #'vc-delete-file)
+ "x" #'vc-delete-file
+ "!" #'vc-edit-next-command)
(fset 'vc-prefix-map vc-prefix-map)
(define-key ctl-x-map "v" 'vc-prefix-map)
diff --git a/lisp/vc/vc-svn.el b/lisp/vc/vc-svn.el
index 08b53a7169f..9c2bdf66746 100644
--- a/lisp/vc/vc-svn.el
+++ b/lisp/vc/vc-svn.el
@@ -207,7 +207,7 @@ switches."
;; dir-status-files called from vc-dir, which loads vc,
;; which loads vc-dispatcher.
-(declare-function vc-exec-after "vc-dispatcher" (code))
+(declare-function vc-exec-after "vc-dispatcher" (code &optional success))
(autoload 'vc-expand-dirs "vc")
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 39a5be6654b..781e7785e41 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -574,6 +574,16 @@
;; containing FILE-OR-DIR. The optional REMOTE-NAME specifies the
;; remote (in Git parlance) whose URL is to be returned. It has
;; only a meaning for distributed VCS and is ignored otherwise.
+;;
+;; - prepare-patch (rev)
+;;
+;; Prepare a patch and return a property list with the keys
+;; `:subject' indicating the patch message as a string, `:buffer'
+;; with a buffer object that contains the entire patch message and
+;; `:body-start' and `:body-end' demarcating what part of said
+;; buffer should be inserted into an inline patch. If the two last
+;; properties are omitted, `point-min' and `point-max' will
+;; respectively be used instead.
;;; Changes from the pre-25.1 API:
;;
@@ -808,12 +818,12 @@ not specific to any particular backend."
(defcustom vc-annotate-switches nil
"A string or list of strings specifying switches for annotate under VC.
When running annotate under a given BACKEND, VC uses the first
-non-nil value of `vc-BACKEND-annotate-switches', `vc-annotate-switches',
-and `annotate-switches', in that order. Since nil means to check the
-next variable in the sequence, either of the first two may use
-the value t to mean no switches at all. `vc-annotate-switches'
-should contain switches that are specific to version control, but
-not specific to any particular backend.
+non-nil value of `vc-BACKEND-annotate-switches' and
+`vc-annotate-switches', in that order. Since nil means to check
+the next variable in the sequence, setting the first to the value
+t means no switches at all. `vc-annotate-switches' should
+contain switches that are specific to version control, but not
+specific to any particular backend.
As very few switches (if any) are used across different VC tools,
please consider using the specific `vc-BACKEND-annotate-switches'
@@ -1014,7 +1024,11 @@ responsible for the given file."
(lambda (backend)
(when-let ((dir (vc-call-backend
backend 'responsible-p file)))
- (cons backend dir)))
+ ;; We run DIR through `expand-file-name'
+ ;; so that abbreviated directories, such
+ ;; as "~/", wouldn't look "less specific"
+ ;; due to their artificially shorter length.
+ (cons backend (expand-file-name dir))))
vc-handled-backends))))
;; Just a single response (or none); use it.
(if (< (length dirs) 2)
@@ -1623,7 +1637,9 @@ Type \\[vc-next-action] to check in changes.")
(format "I stole the lock on %s, " file-description)
(current-time-string)
".\n")
- (message "Please explain why you stole the lock. Type C-c C-c when done.")))
+ (message
+ (substitute-command-keys
+ "Please explain why you stole the lock. Type \\`C-c C-c' when done"))))
(defun vc-checkin (files backend &optional comment initial-contents rev patch-string)
"Check in FILES. COMMENT is a comment string; if omitted, a
@@ -1904,19 +1920,40 @@ Return t if the buffer had changes, nil otherwise."
(defvar vc-revision-history nil
"History for `vc-read-revision'.")
-(defun vc-read-revision (prompt &optional files backend default initial-input)
+(defun vc-read-revision (prompt &optional files backend default initial-input multiple)
+ "Query the user for a revision using PROMPT.
+All subsequent arguments are optional. FILES may specify a file
+set to restrict the revisions to. BACKEND is a VC backend as
+listed in `vc-handled-backends'. DEFAULT and INITIAL-INPUT are
+handled as defined by `completing-read'. If MULTIPLE is non-nil,
+the user may be prompted for multiple revisions. If possible
+this means that `completing-read-multiple' will be used."
(cond
((null files)
(let ((vc-fileset (vc-deduce-fileset t))) ;FIXME: why t? --Stef
(setq files (cadr vc-fileset))
(setq backend (car vc-fileset))))
((null backend) (setq backend (vc-backend (car files)))))
- (let ((completion-table
- (vc-call-backend backend 'revision-completion-table files)))
+ ;; Override any `vc-filter-command-function' value, as user probably
+ ;; doesn't want to edit the command to get the completions.
+ (let* ((vc-filter-command-function #'list)
+ (completion-table
+ (vc-call-backend backend 'revision-completion-table files)))
(if completion-table
- (completing-read prompt completion-table
- nil nil initial-input 'vc-revision-history default)
- (read-string prompt initial-input nil default))))
+ (funcall
+ (if multiple #'completing-read-multiple #'completing-read)
+ prompt completion-table nil nil initial-input 'vc-revision-history default)
+ (let ((answer (read-string prompt initial-input nil default)))
+ (if multiple
+ (split-string answer "[ \t]*,[ \t]*")
+ answer)))))
+
+(defun vc-read-multiple-revisions (prompt &optional files backend default initial-input)
+ "Query the user for multiple revisions.
+This is equivalent to invoking `vc-read-revision' with t for
+MULTIPLE. The arguments PROMPT, FILES, BACKEND, DEFAULT and
+INITIAL-INPUT are passed on to `vc-read-revision' directly."
+ (vc-read-revision prompt files backend default initial-input t))
(defun vc-diff-build-argument-list-internal (&optional fileset)
"Build argument list for calling internal diff functions."
@@ -2756,10 +2793,11 @@ with its diffs (if the underlying VCS supports that)."
;;;###autoload
(defun vc-log-incoming (&optional remote-location)
"Show log of changes that will be received with pull from REMOTE-LOCATION.
-When called interactively with a prefix argument, prompt for REMOTE-LOCATION."
+When called interactively with a prefix argument, prompt for REMOTE-LOCATION.
+In some version control systems REMOTE-LOCATION can be a remote branch name."
(interactive
(when current-prefix-arg
- (list (read-string "Remote location (empty for default): "))))
+ (list (read-string "Remote location/branch (empty for default): "))))
(let ((backend (vc-deduce-backend)))
(unless backend
(error "Buffer is not version controlled"))
@@ -2769,10 +2807,11 @@ When called interactively with a prefix argument, prompt for REMOTE-LOCATION."
;;;###autoload
(defun vc-log-outgoing (&optional remote-location)
"Show log of changes that will be sent with a push operation to REMOTE-LOCATION.
-When called interactively with a prefix argument, prompt for REMOTE-LOCATION."
+When called interactively with a prefix argument, prompt for REMOTE-LOCATION.
+In some version control systems REMOTE-LOCATION can be a remote branch name."
(interactive
(when current-prefix-arg
- (list (read-string "Remote location (empty for default): "))))
+ (list (read-string "Remote location/branch (empty for default): "))))
(let ((backend (vc-deduce-backend)))
(unless backend
(error "Buffer is not version controlled"))
@@ -2959,6 +2998,28 @@ It also signals an error in a Bazaar bound branch."
(vc-call-backend backend 'push arg)
(user-error "VC push is unsupported for `%s'" backend))))
+;;;###autoload
+(defun vc-pull-and-push (&optional arg)
+ "First pull, and then push the current branch.
+The push will only be performed if the pull operation was successful.
+
+You must be visiting a version controlled file, or in a `vc-dir' buffer.
+
+On a distributed version control system, this runs a \"pull\"
+operation on the current branch, prompting for the precise
+command if required. Optional prefix ARG non-nil forces a prompt
+for the VCS command to run. If this is successful, a \"push\"
+operation will then be done.
+
+On a non-distributed version control system, this signals an error.
+It also signals an error in a Bazaar bound branch."
+ (interactive "P")
+ (let* ((vc-fileset (vc-deduce-fileset t))
+ (backend (car vc-fileset)))
+ (if (vc-find-backend-function backend 'pull-and-push)
+ (vc-call-backend backend 'pull-and-push arg)
+ (user-error "VC pull-and-push is unsupported for `%s'" backend))))
+
(defun vc-version-backup-file (file &optional rev)
"Return name of backup file for revision REV of FILE.
If version backups should be used for FILE, and there exists
@@ -3204,6 +3265,139 @@ log entries should be gathered."
(vc-call-backend (vc-responsible-backend default-directory)
'update-changelog args))
+(defvar vc-filter-command-function)
+
+;;;###autoload
+(defun vc-edit-next-command ()
+ "Request editing the next VC shell command before execution.
+This is a prefix command. It affects only a VC command executed
+immediately after this one."
+ (interactive)
+ (letrec ((minibuffer-depth (minibuffer-depth))
+ (command this-command)
+ (keys (key-description (this-command-keys)))
+ (old vc-filter-command-function)
+ (echofun (lambda () keys))
+ (postfun
+ (lambda ()
+ (unless (or (eq this-command command)
+ (> (minibuffer-depth) minibuffer-depth))
+ (remove-hook 'post-command-hook postfun)
+ (remove-hook 'prefix-command-echo-keystrokes-functions
+ echofun)
+ (setq vc-filter-command-function old)))))
+ (add-hook 'post-command-hook postfun)
+ (add-hook 'prefix-command-echo-keystrokes-functions echofun)
+ (setq vc-filter-command-function
+ (lambda (&rest args)
+ (apply #'vc-user-edit-command (apply old args))))))
+
+(defcustom vc-prepare-patches-separately t
+ "Whether `vc-prepare-patch' should generate a separate message for each patch.
+If nil, `vc-prepare-patch' creates a single email message by attaching
+all the patches to the body of that message. If non-nil, each patch
+will be sent out in a separate message, and the messages will be
+prepared sequentially."
+ :type 'boolean
+ :safe #'booleanp
+ :version "29.1")
+
+(defcustom vc-default-patch-addressee nil
+ "Default addressee for `vc-prepare-patch'.
+If nil, no default will be used. This option may be set locally."
+ :type '(choice (const :tag "No default" nil)
+ (string :tag "Addressee"))
+ :safe #'stringp
+ :version "29.1")
+
+(declare-function message--name-table "message" (orig-string))
+(declare-function mml-attach-buffer "mml"
+ (buffer &optional type description disposition))
+(declare-function log-view-get-marked "log-view" ())
+
+(defun vc-default-prepare-patch (_backend rev)
+ (let ((backend (vc-backend buffer-file-name)))
+ (with-current-buffer (generate-new-buffer " *vc-default-prepare-patch*")
+ (vc-diff-internal
+ nil (list backend) rev
+ (vc-call-backend backend 'previous-revision
+ buffer-file-name rev)
+ nil t)
+ (list :subject (concat "Patch for "
+ (file-name-nondirectory
+ (directory-file-name
+ (vc-root-dir))))
+ :buffer (current-buffer)))))
+
+;;;###autoload
+(defun vc-prepare-patch (addressee subject revisions)
+ "Compose an Email sending patches for REVISIONS to ADDRESSEE.
+If `vc-prepare-patches-separately' is nil, SUBJECT will be used
+as the default subject for the message (and it will be prompted
+for when called interactively). Otherwise a separate message
+will be composed for each revision, with SUBJECT derived from the
+invidividual commits.
+
+When invoked interactively in a Log View buffer with marked
+revisions, those revisions will be used."
+ (interactive
+ (let ((revs (vc-read-multiple-revisions
+ "Revisions: " nil nil nil
+ (or (and-let* ((revs (log-view-get-marked)))
+ (mapconcat #'identity revs ","))
+ (and-let* ((file (buffer-file-name)))
+ (vc-working-revision file)))))
+ to)
+ (require 'message)
+ (while (null (setq to (completing-read-multiple
+ (format-prompt
+ "Addressee"
+ vc-default-patch-addressee)
+ (message--name-table "")
+ nil nil nil nil
+ vc-default-patch-addressee)))
+ (message "At least one addressee required.")
+ (sit-for blink-matching-delay))
+ (list (string-join to ", ")
+ (and (not vc-prepare-patches-separately)
+ (read-string "Subject: " "[PATCH] " nil nil t))
+ revs)))
+ (save-current-buffer
+ (vc-ensure-vc-buffer)
+ (let ((patches (mapcar (lambda (rev)
+ (vc-call-backend
+ (vc-responsible-backend default-directory)
+ 'prepare-patch rev))
+ revisions)))
+ (if vc-prepare-patches-separately
+ (dolist (patch (reverse patches)
+ (message "Prepared %d patches..." (length patches)))
+ (compose-mail addressee
+ (plist-get patch :subject)
+ nil nil nil nil
+ `((kill-buffer ,(plist-get patch :buffer))
+ (exit-recursive-edit)))
+ (rfc822-goto-eoh) (forward-line)
+ (save-excursion ;don't jump to the end
+ (insert-buffer-substring
+ (plist-get patch :buffer)
+ (plist-get patch :body-start)
+ (plist-get patch :body-end))))
+ (compose-mail addressee subject nil nil nil nil
+ (mapcar
+ (lambda (p)
+ (list #'kill-buffer (plist-get p :buffer)))
+ patches))
+ (rfc822-goto-eoh)
+ (forward-line)
+ (save-excursion
+ (dolist (patch patches)
+ (mml-attach-buffer (buffer-name (plist-get patch :buffer))
+ "text/x-patch"
+ (plist-get patch :subject)
+ "attachment")))
+ (open-line 2)))))
+
(defun vc-default-responsible-p (_backend _file)
"Indicate whether BACKEND is responsible for FILE.
The default is to return nil always."
diff --git a/lisp/view.el b/lisp/view.el
index 1207f01db21..d9b1a2d0e7d 100644
--- a/lisp/view.el
+++ b/lisp/view.el
@@ -68,13 +68,6 @@ the F command in `view-mode', but you can set it to t if you want the action
for all scroll commands in view mode."
:type 'boolean)
-;;;###autoload
-(defcustom view-remove-frame-by-deleting t
- "Determine how View mode removes a frame no longer needed.
-If nil, make an icon of the frame. If non-nil, delete the frame."
- :type 'boolean
- :version "23.1")
-
(defcustom view-exits-all-viewing-windows nil
"Non-nil means restore all windows used to view buffer.
Commands that restore windows when finished viewing a buffer,
diff --git a/lisp/whitespace.el b/lisp/whitespace.el
index ae4d8ae3f06..d7b83ef34a5 100644
--- a/lisp/whitespace.el
+++ b/lisp/whitespace.el
@@ -2385,38 +2385,39 @@ purposes)."
(save-excursion
(save-restriction
(widen)
- (when (or (null beg)
- (<= beg (save-excursion
- (goto-char whitespace-bob-marker)
- ;; Any change in the first non-`empty'
- ;; line, even if it's not the first
- ;; character in the line, can potentially
- ;; cause subsequent lines to become
- ;; classified as `empty' (e.g., delete the
- ;; "x" from " x").
- (forward-line 1)
- (point))))
- (goto-char 1)
- (set-marker whitespace-bob-marker (point))
- (save-match-data
- (when (looking-at whitespace-empty-at-bob-regexp)
- (set-marker whitespace-bob-marker (match-end 1))
- (put-text-property (match-beginning 1) (match-end 1)
- 'font-lock-multiline t))))
- (when (or (null end)
- (>= end (save-excursion
- (goto-char whitespace-eob-marker)
- ;; See above comment for the BoB case.
- (forward-line -1)
- (point))))
- (goto-char (1+ (buffer-size)))
- (set-marker whitespace-eob-marker (point))
- (save-match-data
- (when (whitespace--looking-back
- whitespace-empty-at-eob-regexp)
- (set-marker whitespace-eob-marker (match-beginning 1))
- (put-text-property (match-beginning 1) (match-end 1)
- 'font-lock-multiline t))))))))
+ (let ((inhibit-read-only t))
+ (when (or (null beg)
+ (<= beg (save-excursion
+ (goto-char whitespace-bob-marker)
+ ;; Any change in the first non-`empty'
+ ;; line, even if it's not the first
+ ;; character in the line, can potentially
+ ;; cause subsequent lines to become
+ ;; classified as `empty' (e.g., delete the
+ ;; "x" from " x").
+ (forward-line 1)
+ (point))))
+ (goto-char 1)
+ (set-marker whitespace-bob-marker (point))
+ (save-match-data
+ (when (looking-at whitespace-empty-at-bob-regexp)
+ (set-marker whitespace-bob-marker (match-end 1))
+ (put-text-property (match-beginning 1) (match-end 1)
+ 'font-lock-multiline t))))
+ (when (or (null end)
+ (>= end (save-excursion
+ (goto-char whitespace-eob-marker)
+ ;; See above comment for the BoB case.
+ (forward-line -1)
+ (point))))
+ (goto-char (1+ (buffer-size)))
+ (set-marker whitespace-eob-marker (point))
+ (save-match-data
+ (when (whitespace--looking-back
+ whitespace-empty-at-eob-regexp)
+ (set-marker whitespace-eob-marker (match-beginning 1))
+ (put-text-property (match-beginning 1) (match-end 1)
+ 'font-lock-multiline t)))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/lisp/wid-browse.el b/lisp/wid-browse.el
index 7fc476e5dfd..a90f7bc160b 100644
--- a/lisp/wid-browse.el
+++ b/lisp/wid-browse.el
@@ -35,12 +35,10 @@
;;; The Mode.
-(defvar widget-browse-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map widget-keymap)
- (define-key map "q" #'bury-buffer)
- map)
- "Keymap for `widget-browse-mode'.")
+(defvar-keymap widget-browse-mode-map
+ :doc "Keymap for `widget-browse-mode'."
+ :parent widget-keymap
+ "q" #'bury-buffer)
(easy-menu-define widget-browse-mode-customize-menu
widget-browse-mode-map
@@ -245,11 +243,9 @@ VALUE is assumed to be a list of widgets."
;;; Widget Minor Mode.
-(defvar widget-minor-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map widget-keymap)
- map)
- "Keymap used in Widget Minor Mode.")
+(defvar-keymap widget-minor-mode-map
+ :doc "Keymap used in Widget Minor Mode."
+ :parent widget-keymap)
;;;###autoload
(define-minor-mode widget-minor-mode
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 9aec6b02441..4d9663cea95 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -3452,11 +3452,9 @@ It reads a directory name from an editable text field."
(defvar widget-key-sequence-default-value [ignore]
"Default value for an empty key sequence.")
-(defvar widget-key-sequence-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map widget-field-keymap)
- (define-key map [(control ?q)] 'widget-key-sequence-read-event)
- map))
+(defvar-keymap widget-key-sequence-map
+ :parent widget-field-keymap
+ "C-q" #'widget-key-sequence-read-event)
(define-widget 'key-sequence 'restricted-sexp
"A key sequence. This is obsolete; use the `key' type instead."
diff --git a/lisp/window.el b/lisp/window.el
index d5f42dd10b4..905803b19e6 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -10593,7 +10593,8 @@ displaying that processes's buffer."
"2" #'split-root-window-below
"3" #'split-root-window-right
"s" #'window-toggle-side-windows
- "f" #'tear-off-window
+ "^ f" #'tear-off-window
+ "^ t" #'tab-window-detach
"-" #'fit-window-to-buffer
"0" #'delete-windows-on)
(define-key ctl-x-map "w" window-prefix-map)
diff --git a/lisp/winner.el b/lisp/winner.el
index 4290f1fd239..174b698e7b5 100644
--- a/lisp/winner.el
+++ b/lisp/winner.el
@@ -171,8 +171,7 @@ You may want to include buffer names such as *Help*, *Apropos*,
(/= 0 (minibuffer-depth)))
(push (selected-frame) winner-modified-list)))
-;; A `post-command-hook' for emacsen with
-;; `window-configuration-change-hook'.
+;; Used as `post-command-hook'.
(defun winner-save-old-configurations ()
(when (zerop (minibuffer-depth))
(unless (eq this-command winner-last-command)
@@ -191,8 +190,7 @@ You may want to include buffer names such as *Help*, *Apropos*,
(winner-insert-if-new (selected-frame))
(winner-remember))
-;; A `post-command-hook' for other emacsen.
-;; Also called by `winner-undo' before "undoing".
+;; Called by `winner-undo' before "undoing".
(defun winner-save-conditionally ()
(when (zerop (minibuffer-depth))
(winner-save-unconditionally)))
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el
index 2bda67fe3f3..ee80e41a22e 100644
--- a/lisp/x-dnd.el
+++ b/lisp/x-dnd.el
@@ -1640,8 +1640,9 @@ VERSION is the version of the XDND protocol understood by SOURCE."
desired-name
(or file-name-coding-system
default-file-name-coding-system)))
- (let ((name (funcall x-dnd-direct-save-function
- t desired-name)))
+ (let ((name (expand-file-name
+ (funcall x-dnd-direct-save-function
+ t desired-name))))
(setq save-to name save-to-remote name))
(when save-to
(if (file-remote-p save-to)
diff --git a/lisp/xdg.el b/lisp/xdg.el
index dd0d51290dc..82f1f07df54 100644
--- a/lisp/xdg.el
+++ b/lisp/xdg.el
@@ -30,6 +30,7 @@
;; - Thumbnail Managing Standard
;; - xdg-user-dirs configuration
;; - Desktop Entry Specification
+;; - Unofficial extension $XDG_SESSION_TYPE from systemd
;;; Code:
@@ -281,6 +282,18 @@ Optional argument GROUP defaults to the string \"Desktop Entry\"."
(when (null (string-match-p "[^[:blank:]]" (car res))) (pop res))
(nreverse res)))
+(defun xdg-current-desktop ()
+ "Return a list of strings identifying the current desktop environment.
+
+According to the XDG Desktop Entry Specification version 0.5:
+
+ If $XDG_CURRENT_DESKTOP is set then it contains a
+ colon-separated list of strings ... $XDG_CURRENT_DESKTOP
+ should have been set by the login manager, according to the
+ value of the DesktopNames found in the session file."
+ (when-let ((ret (getenv "XDG_CURRENT_DESKTOP")))
+ (string-split ret ":")))
+
;; MIME apps specification
;; https://standards.freedesktop.org/mime-apps-spec/mime-apps-spec-1.0.1.html
@@ -385,6 +398,18 @@ Results are cached in `xdg-mime-table'."
(put 'xdg-mime-table 'mtime (current-time)))
(puthash subtype (delq nil files) (cdr (assoc type xdg-mime-table)))))))
+
+;; Unofficial extension from systemd.
+
+(defun xdg-session-type ()
+ "Return the value of $XDG_SESSION_TYPE.
+Should be one of \"unspecified\", \"tty\", \"x11\", \"wayland\",
+or \"mir\".
+
+This is not part of any official Freedesktop.org standard, but is
+documented in the man page `pam_systemd'."
+ (getenv "XDG_SESSION_TYPE"))
+
(provide 'xdg)
;;; xdg.el ends here
diff --git a/m4/assert_h.m4 b/m4/assert_h.m4
new file mode 100644
index 00000000000..c1306daef4f
--- /dev/null
+++ b/m4/assert_h.m4
@@ -0,0 +1,61 @@
+# assert-h.m4
+dnl Copyright (C) 2011-2022 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+AC_DEFUN([gl_ASSERT_H],
+[
+ AC_CACHE_CHECK([for static_assert], [gl_cv_static_assert],
+ [gl_save_CFLAGS=$CFLAGS
+ for gl_working in "yes, a keyword" "yes, an <assert.h> macro"; do
+ AS_CASE([$gl_working],
+ [*assert.h*], [CFLAGS="$gl_save_CFLAGS -DINCLUDE_ASSERT_H"])
+
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#if defined __clang__ && __STDC_VERSION__ < 202311
+ #pragma clang diagnostic error "-Wc2x-extensions"
+ #pragma clang diagnostic error "-Wc++17-extensions"
+ #endif
+ #ifdef INCLUDE_ASSERT_H
+ #include <assert.h>
+ #endif
+ static_assert (2 + 2 == 4, "arithmetic does not work");
+ static_assert (2 + 2 == 4);
+ ]],
+ [[
+ static_assert (sizeof (char) == 1, "sizeof does not work");
+ static_assert (sizeof (char) == 1);
+ ]])],
+ [gl_cv_static_assert=$gl_working],
+ [gl_cv_static_assert=no])
+ CFLAGS=$gl_save_CFLAGS
+ test "$gl_cv_static_assert" != no && break
+ done])
+
+ GL_GENERATE_ASSERT_H=false
+ AS_CASE([$gl_cv_static_assert],
+ [yes*keyword*],
+ [AC_DEFINE([HAVE_C_STATIC_ASSERT], [1],
+ [Define to 1 if the static_assert keyword works.])],
+ [no],
+ [GL_GENERATE_ASSERT_H=true
+ gl_NEXT_HEADERS([assert.h])])
+
+ dnl The "zz" puts this toward config.h's end, to avoid potential
+ dnl collisions with other definitions. #undef assert so that
+ dnl programs are not tempted to use it without specifically
+ dnl including assert.h. Break the #undef apart with a comment
+ dnl so that 'configure' does not comment it out.
+ AH_VERBATIM([zzstatic_assert],
+[#if (!defined HAVE_C_STATIC_ASSERT && !defined assert \
+ && (!defined __cplusplus \
+ || (__cpp_static_assert < 201411 \
+ && __GNUG__ < 6 && __clang_major__ < 6)))
+ #include <assert.h>
+ #undef/**/assert
+#endif])
+])
diff --git a/m4/c-bool.m4 b/m4/c-bool.m4
new file mode 100644
index 00000000000..bb109b77968
--- /dev/null
+++ b/m4/c-bool.m4
@@ -0,0 +1,51 @@
+# Check for bool that conforms to C2023.
+
+dnl Copyright 2022 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_C_BOOL],
+[
+ AC_CACHE_CHECK([for bool, true, false], [gl_cv_c_bool],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([[
+ #if true == false
+ #error "true == false"
+ #endif
+ extern bool b;
+ bool b = true == false;]])],
+ [gl_cv_c_bool=yes],
+ [gl_cv_c_bool=no])])
+ if test "$gl_cv_c_bool" = yes; then
+ AC_DEFINE([HAVE_C_BOOL], [1],
+ [Define to 1 if bool, true and false work as per C2023.])
+ fi
+
+ AC_CHECK_HEADERS_ONCE([stdbool.h])
+
+ dnl The "zz" puts this toward config.h's end, to avoid potential
+ dnl collisions with other definitions.
+ dnl If 'bool', 'true' and 'false' do not work, arrange for them to work.
+ dnl In C, this means including <stdbool.h> if it is not already included.
+ dnl However, if the preprocessor mistakenly treats 'true' as 0,
+ dnl define it to a bool expression equal to 1; this is needed in
+ dnl Sun C++ 5.11 (Oracle Solaris Studio 12.2, 2010) and older.
+ AH_VERBATIM([zzbool],
+[#ifndef HAVE_C_BOOL
+# if !defined __cplusplus && !defined __bool_true_false_are_defined
+# if HAVE_STDBOOL_H
+# include <stdbool.h>
+# else
+# if defined __SUNPRO_C
+# error "<stdbool.h> is not usable with this configuration. To make it usable, add -D_STDC_C99= to $CC."
+# else
+# error "<stdbool.h> does not exist on this platform. Use gnulib module 'stdbool-c99' instead of gnulib module 'stdbool'."
+# endif
+# endif
+# endif
+# if !true
+# define true (!false)
+# endif
+#endif])
+])
diff --git a/m4/gettime.m4 b/m4/gettime.m4
index f0aeb4d0e4d..c3e0713b575 100644
--- a/m4/gettime.m4
+++ b/m4/gettime.m4
@@ -1,4 +1,4 @@
-# gettime.m4 serial 11
+# gettime.m4 serial 12
dnl Copyright (C) 2002, 2004-2006, 2009-2022 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -9,7 +9,34 @@ AC_DEFUN([gl_GETTIME],
dnl Prerequisites of lib/gettime.c.
AC_REQUIRE([gl_CLOCK_TIME])
AC_REQUIRE([gl_TIMESPEC])
- AC_CHECK_FUNCS_ONCE([timespec_get])
+
+ AC_REQUIRE([gl_CHECK_FUNC_TIMESPEC_GET])
+ if test $gl_cv_func_timespec_get = yes; then
+ AC_DEFINE([HAVE_TIMESPEC_GET], [1],
+ [Define if you have the timespec_get function.])
+ fi
+])
+
+dnl Tests whether the function timespec_get exists.
+dnl Sets gl_cv_func_timespec_get.
+AC_DEFUN([gl_CHECK_FUNC_TIMESPEC_GET],
+[
+ dnl Persuade OpenBSD <time.h> to declare timespec_get().
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+
+ dnl We can't use AC_CHECK_FUNC here, because timespec_get() is defined as a
+ dnl static inline function in <time.h> on MSVC 14.
+ AC_CACHE_CHECK([for timespec_get], [gl_cv_func_timespec_get],
+ [AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <time.h>
+ struct timespec ts;
+ ]],
+ [[return timespec_get (&ts, 0);]])
+ ],
+ [gl_cv_func_timespec_get=yes],
+ [gl_cv_func_timespec_get=no])
+ ])
])
AC_DEFUN([gl_GETTIME_RES],
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index 8a5daa230e3..d17cbec58cb 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -1,4 +1,4 @@
-# gnulib-common.m4 serial 73
+# gnulib-common.m4 serial 74
dnl Copyright (C) 2007-2022 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -115,7 +115,7 @@ AC_DEFUN([gl_COMMON_BODY], [
# define _GL_HAS_C_ATTRIBUTE(attr) 0
#endif
-]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's _Alignas instead.
+]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's alignas instead.
[
/* _GL_ATTRIBUTE_ALLOC_SIZE ((N)) declares that the Nth argument of the function
is the size of the returned memory block.
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 0c43dde716c..f1ac4991324 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -46,6 +46,7 @@ AC_DEFUN([gl_EARLY],
# Code from module acl-permissions:
# Code from module alloca-opt:
# Code from module allocator:
+ # Code from module assert-h:
# Code from module at-internal:
# Code from module attribute:
# Code from module binary-io:
@@ -122,8 +123,8 @@ AC_DEFUN([gl_EARLY],
# Code from module intprops:
# Code from module inttypes-incomplete:
# Code from module largefile:
- AC_REQUIRE([AC_SYS_LARGEFILE])
AC_REQUIRE([gl_YEAR2038_EARLY])
+ AC_REQUIRE([AC_SYS_LARGEFILE])
# Code from module lchmod:
# Code from module libc-config:
# Code from module libgmp:
@@ -171,6 +172,7 @@ AC_DEFUN([gl_EARLY],
# Code from module stat-time:
# Code from module std-gnu11:
# Code from module stdalign:
+ # Code from module stdbool:
# Code from module stdckdint:
# Code from module stddef:
# Code from module stdint:
@@ -233,6 +235,9 @@ AC_DEFUN([gl_INIT],
gl_FUNC_ALLOCA
gl_CONDITIONAL_HEADER([alloca.h])
AC_PROG_MKDIR_P
+ gl_ASSERT_H
+ gl_CONDITIONAL_HEADER([assert.h])
+ AC_PROG_MKDIR_P
gl___BUILTIN_EXPECT
gl_BYTESWAP
gl_CONDITIONAL_HEADER([byteswap.h])
@@ -486,6 +491,7 @@ AC_DEFUN([gl_INIT],
gl_STDALIGN_H
gl_CONDITIONAL_HEADER([stdalign.h])
AC_PROG_MKDIR_P
+ gl_C_BOOL
gl_STDDEF_H
gl_STDDEF_H_REQUIRE_DEFAULTS
gl_CONDITIONAL_HEADER([stddef.h])
@@ -1214,6 +1220,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/allocator.c
lib/allocator.h
lib/arg-nonnull.h
+ lib/assert.in.h
lib/at-func.c
lib/attribute.h
lib/binary-io.c
@@ -1420,8 +1427,10 @@ AC_DEFUN([gl_FILE_LIST], [
m4/absolute-header.m4
m4/acl.m4
m4/alloca.m4
+ m4/assert_h.m4
m4/builtin-expect.m4
m4/byteswap.m4
+ m4/c-bool.m4
m4/canonicalize.m4
m4/clock_time.m4
m4/copy-file-range.m4
diff --git a/m4/nanosleep.m4 b/m4/nanosleep.m4
index 1964b1ea47d..dfe21f56d5c 100644
--- a/m4/nanosleep.m4
+++ b/m4/nanosleep.m4
@@ -1,4 +1,4 @@
-# serial 41
+# serial 42
dnl From Jim Meyering.
dnl Check for the nanosleep function.
@@ -100,15 +100,22 @@ AC_DEFUN([gl_FUNC_NANOSLEEP],
#else /* A simpler test for native Windows. */
if (nanosleep (&ts_sleep, &ts_remaining) < 0)
return 3;
+ /* Test for 32-bit mingw bug: negative nanosecond values do not
+ cause failure. */
+ ts_sleep.tv_sec = 1;
+ ts_sleep.tv_nsec = -1;
+ if (nanosleep (&ts_sleep, &ts_remaining) != -1)
+ return 7;
#endif
return 0;
}]])],
[gl_cv_func_nanosleep=yes],
- [case $? in dnl (
- 4|5|6) gl_cv_func_nanosleep='no (mishandles large arguments)';; dnl (
- *) gl_cv_func_nanosleep=no;;
+ [case $? in
+ 4|5|6) gl_cv_func_nanosleep='no (mishandles large arguments)' ;;
+ 7) gl_cv_func_nanosleep='no (mishandles negative tv_nsec)' ;;
+ *) gl_cv_func_nanosleep=no ;;
esac],
- [case "$host_os" in dnl ((
+ [case "$host_os" in
linux*) # Guess it halfway works when the kernel is Linux.
gl_cv_func_nanosleep='guessing no (mishandles large arguments)' ;;
mingw*) # Guess no on native Windows.
diff --git a/m4/stdalign.m4 b/m4/stdalign.m4
index 78577cb2acc..324e91dae2e 100644
--- a/m4/stdalign.m4
+++ b/m4/stdalign.m4
@@ -1,4 +1,4 @@
-# Check for stdalign.h that conforms to C11.
+# Check for alignas and alignof that conform to C23.
dnl Copyright 2011-2022 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
@@ -9,12 +9,18 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_STDALIGN_H],
[
- AC_CACHE_CHECK([for working stdalign.h],
+ AC_CACHE_CHECK([for alignas and alignof],
[gl_cv_header_working_stdalign_h],
- [AC_COMPILE_IFELSE(
+ [gl_save_CFLAGS=$CFLAGS
+ for gl_working in "yes, keywords" "yes, <stdalign.h> macros"; do
+ AS_CASE([$gl_working],
+ [*stdalign.h*], [CFLAGS="$gl_save_CFLAGS -DINCLUDE_STDALIGN_H"])
+ AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stdint.h>
- #include <stdalign.h>
+ #ifdef INCLUDE_STDALIGN_H
+ #include <stdalign.h>
+ #endif
#include <stddef.h>
/* Test that alignof yields a result consistent with offsetof.
@@ -30,7 +36,7 @@ AC_DEFUN([gl_STDALIGN_H],
char test_long[ao (long int) % _Alignof (long int) == 0 ? 1 : -1];
char test_alignof[alignof (double) == _Alignof (double) ? 1 : -1];
- /* Test _Alignas only on platforms where gnulib can help. */
+ /* Test alignas only on platforms where gnulib can help. */
#if \
((defined __cplusplus && 201103 <= __cplusplus) \
|| (__TINYC__ && defined __attribute__) \
@@ -45,12 +51,84 @@ AC_DEFUN([gl_STDALIGN_H],
? 1 : -1];
#endif
]])],
- [gl_cv_header_working_stdalign_h=yes],
- [gl_cv_header_working_stdalign_h=no])])
-
- if test $gl_cv_header_working_stdalign_h = yes; then
- GL_GENERATE_STDALIGN_H=false
- else
- GL_GENERATE_STDALIGN_H=true
- fi
+ [gl_cv_header_working_stdalign_h=$gl_working],
+ [gl_cv_header_working_stdalign_h=no])
+
+ CFLAGS=$gl_save_CFLAGS
+ test "$gl_cv_header_working_stdalign_h" != no && break
+ done])
+
+ GL_GENERATE_STDALIGN_H=false
+ AS_CASE([$gl_cv_header_working_stdalign_h],
+ [no],
+ [GL_GENERATE_STDALIGN_H=true],
+ [yes*keyword*],
+ [AC_DEFINE([HAVE_C_ALIGNASOF], [1],
+ [Define to 1 if the alignas and alignof keywords work.])])
+
+ AC_CHECK_HEADERS_ONCE([stdalign.h])
+
+ dnl The "zz" puts this toward config.h's end, to avoid potential
+ dnl collisions with other definitions.
+ AH_VERBATIM([zzalignas],
+[#if !defined HAVE_C_ALIGNASOF && __cplusplus < 201103 && !defined alignof
+# if HAVE_STDALIGN_H
+# include <stdalign.h>
+# else
+ /* Substitute. Keep consistent with gnulib/lib/stdalign.in.h. */
+# ifndef _GL_STDALIGN_H
+# define _GL_STDALIGN_H
+# undef _Alignas
+# undef _Alignof
+# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \
+ || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
+ && !defined __clang__) \
+ || (defined __clang__ && __clang_major__ < 8))
+# ifdef __cplusplus
+# if (201103 <= __cplusplus || defined _MSC_VER)
+# define _Alignof(type) alignof (type)
+# else
+ template <class __t> struct __alignof_helper { char __a; __t __b; };
+# define _Alignof(type) offsetof (__alignof_helper<type>, __b)
+# define _GL_STDALIGN_NEEDS_STDDEF 1
+# endif
+# else
+# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b)
+# define _GL_STDALIGN_NEEDS_STDDEF 1
+# endif
+# endif
+# if ! (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))
+# define alignof _Alignof
+# endif
+# define __alignof_is_defined 1
+# if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
+# if defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)
+# define _Alignas(a) alignas (a)
+# elif (!defined __attribute__ \
+ && ((defined __APPLE__ && defined __MACH__ \
+ ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \
+ : __GNUC__ && !defined __ibmxl__) \
+ || (4 <= __clang_major__) \
+ || (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \
+ || __ICC || 0x590 <= __SUNPRO_C || 0x0600 <= __xlC__))
+# define _Alignas(a) __attribute__ ((__aligned__ (a)))
+# elif 1300 <= _MSC_VER
+# define _Alignas(a) __declspec (align (a))
+# endif
+# endif
+# if ((defined _Alignas \
+ && !(defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))) \
+ || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__))
+# define alignas _Alignas
+# endif
+# if (defined alignas \
+ || (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)))
+# define __alignas_is_defined 1
+# endif
+# if _GL_STDALIGN_NEEDS_STDDEF
+# include <stddef.h>
+# endif
+# endif /* _GL_STDALIGN_H */
+# endif
+#endif])
])
diff --git a/m4/time_h.m4 b/m4/time_h.m4
index 98d7b6e01bd..4ac8fd00752 100644
--- a/m4/time_h.m4
+++ b/m4/time_h.m4
@@ -2,7 +2,7 @@
# Copyright (C) 2000-2001, 2003-2007, 2009-2022 Free Software Foundation, Inc.
-# serial 19
+# serial 20
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -19,6 +19,12 @@ AC_DEFUN_ONCE([gl_TIME_H],
gl_NEXT_HEADERS([time.h])
AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC])
+ dnl Check for declarations of anything we want to poison if the
+ dnl corresponding gnulib module is not in use.
+ gl_WARN_ON_USE_PREPARE([[
+#include <time.h>
+ ]], [asctime_r ctime_r])
+
AC_REQUIRE([AC_C_RESTRICT])
AC_CACHE_CHECK([for TIME_UTC in <time.h>],
diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp
index 8728c8dac48..ff6be8d0830 100644
--- a/msdos/sed2v2.inp
+++ b/msdos/sed2v2.inp
@@ -114,6 +114,7 @@ s/^#undef POINTER_TYPE *$/#define POINTER_TYPE void/
#else\
#undef HAVE_INTTYPES_H\
#endif
+s/^#undef HAVE_STDBOOL_H/#define HAVE_STDBOOL_H 1/
/^#undef HAVE_STDINT_H/c\
#if __DJGPP__ > 2 || __DJGPP_MINOR__ > 3\
#define HAVE_STDINT_H 1\
diff --git a/msdos/sedlibmk.inp b/msdos/sedlibmk.inp
index 79430bbaf1d..3af0db6e0a5 100644
--- a/msdos/sedlibmk.inp
+++ b/msdos/sedlibmk.inp
@@ -182,6 +182,7 @@ s/@PACKAGE@/emacs/
/^GL_GNULIB_GETLOADAVG *=/s/@GL_GNULIB_GETLOADAVG@/1/
/^GL_GNULIB_GETRANDOM *=/s/@GL_GNULIB_GETRANDOM@/1/
/^GL_GNULIB_UNISTD_H_GETOPT *=/s/@GL_GNULIB_UNISTD_H_GETOPT@/1/
+/^GL_GNULIB_LCHMOD *=/s/@GL_GNULIB_LCHMOD@/1/
/^GL_GNULIB_MEMMEM *=/s/@GL_GNULIB_MEMMEM@/1/
/^GL_GNULIB_MEMRCHR *=/s/@GL_GNULIB_MEMRCHR@/1/
/^GL_GNULIB_MEMPCPY *=/s/@GL_GNULIB_MEMPCPY@/1/
@@ -216,7 +217,8 @@ s/@PACKAGE@/emacs/
/^HAVE_GETHOSTNAME *=/s/@HAVE_GETHOSTNAME@/1/
/^HAVE_GETLOGIN *=/s/@HAVE_GETLOGIN@/1/
/^HAVE_GETPAGESIZE *=/s/@HAVE_GETPAGESIZE@/1/
-/^HAVE_INTTYPES_H *=/s/@HAVE_INTTYPES_H@/HAVE_INTTYPES_H/
+/^HAVE_INTTYPES_H *=/s/@HAVE_INTTYPES_H@/1/
+/^HAVE_LCHMOD *=/s/@HAVE_LCHMOD@/0/
/^HAVE_LINK *=/s/@HAVE_LINK@/1/
/^HAVE_LONG_LONG_INT *=/s/@HAVE_LONG_LONG_INT@/1/
/^HAVE_LSTAT *=/s/@HAVE_LSTAT@/HAVE_LSTAT/
@@ -293,7 +295,8 @@ s/@PACKAGE@/emacs/
/^NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H *=/s/@[^@\n]*@//
/^NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H *=/s!@[^@\n]*@!<sys/types.h>!
/^NEXT_AS_FIRST_DIRECTIVE_TIME_H *=/s/@[^@\n]*@/<time.h>/
-/^NEXT_AS_FIRST_DIRECTIVE_UNISTD_H *=/s/@[^@\n]*@/<unistd.h>/
+/^NEXT_ASSERT_H *=/s/@[^@\n]*@/<assert.h>/
+/^NEXT_DIRENT_H *=/s/@[^@\n]*@/<dirent.h>/
/^NEXT_DIRENT_H *=/s/@[^@\n]*@/<dirent.h>/
/^NEXT_ERRNO_H *=/s/@[^@\n]*@//
/^NEXT_FCNTL_H *=/s/@[^@\n]*@/<fcntl.h>/
@@ -323,6 +326,7 @@ s/@PACKAGE@/emacs/
/^LIB_GETRANDOM[^ =]* *= *@/s/@[^@\n]*@//
/^SIG_ATOMIC_T_SUFFIX *=/s/@SIG_ATOMIC_T_SUFFIX@//
/^SIZE_T_SUFFIX *=/s/@SIZE_T_SUFFIX@/u/
+/^ASSERT_H *=/s/@[^@\n]*@/assert.h/
/^ALLOCA_H *=/s/@[^@\n]*@/alloca.h/
/^BYTESWAP_H *=/s/@[^@\n]*@/byteswap.h/
/^DIRENT_H *=/s/@[^@\n]*@//
@@ -412,6 +416,9 @@ s/^ -*test -z.*|| rm/ -rm/
s/@echo /@djecho /
#
# Determine which headers to generate
+# DJGPP assert.h lacks static_assert, so assert.h will have to be
+# generated
+s/= @GL_GENERATE_ASSERT_H_CONDITION@/= 1/
s/= @GL_GENERATE_ALLOCA_H_CONDITION@/= 1/
s/= @GL_GENERATE_BYTESWAP_H_CONDITION@/= 1/
s/= @GL_GENERATE_EXECINFO_H_CONDITION@/= 1/
@@ -497,6 +504,14 @@ s/\.in-h\; *\\$/.in-h >> $@-t/
s/'\; \\ *$/' >> $@-t/
/< \$(srcdir)\/string\.in-h >>/d
}
+/^assert\.h/,/^ \$(AM_V_AT)mv \$@-t \$@/{
+ s/\$(gl_V_at){/\$(gl_V_at)/
+ s/< \$(srcdir)\/assert\.in-h/& > $@-t/
+ s/ sed/ \$(gl_V_at) \$(SED_HEADER_STDOUT)\\\
+ /
+ s/\} > \$@-t/>> $@-t/
+ s/< \$(srcdir)\/verify\.h; \\/\$(srcdir)\/verify\.h >> \$@-t/
+}
s!\$(MKDIR_P)[ ][ ]*sys!command.com /c "if not exist sys\\stat.h md sys"!
/^ @for dir in/,/^[^ ]/c\
-rm -rf $(MOSTLYCLEANDIRS)
diff --git a/nextstep/Makefile.in b/nextstep/Makefile.in
index 82bf13bc929..c1200f73fbd 100644
--- a/nextstep/Makefile.in
+++ b/nextstep/Makefile.in
@@ -59,7 +59,7 @@ ${ns_appdir}: ${srcdir}/${ns_appsrc} ${ns_appsrc}
${MKDIR_P} ${ns_appdir}
( cd ${srcdir}/${ns_appsrc} ; tar cfh - . ) | \
( cd ${ns_appdir} ; umask 022; tar xf - )
- [ "`cd ${srcdir} && /bin/pwd`" = "`/bin/pwd`" ] || \
+ [ "`cd ${srcdir} && pwd -P`" = "`pwd -P`" ] || \
( cd ${ns_appsrc} ; tar cfh - . ) | \
( cd ${ns_appdir} ; umask 022; tar xf - )
touch ${ns_appdir}
diff --git a/nt/INSTALL b/nt/INSTALL
index 0b8ca98c8ad..81d4c6293c5 100644
--- a/nt/INSTALL
+++ b/nt/INSTALL
@@ -214,7 +214,7 @@ build will run on Windows 9X and newer systems).
of the 'bsdtar' program to unpack the tarballs. 'bsdtar' is
available as part of the 'libarchive' package from here:
- http://sourceforge.net/projects/ezwinports/files/
+ https://sourceforge.net/projects/ezwinports/files/
The recommended place to install these packages is a single tree
starting from some directory on a drive other than the system drive
@@ -242,16 +242,16 @@ build will run on Windows 9X and newer systems).
. Texinfo (needed to produce the Info manuals when building from
the repository, and for "make install")
- Available from http://sourceforge.net/projects/ezwinports/files/.
+ Available from https://sourceforge.net/projects/ezwinports/files/.
. pkg-config (invoked by the configure script to look for optional
packages)
- Available from http://sourceforge.net/projects/ezwinports/files/.
+ Available from https://sourceforge.net/projects/ezwinports/files/.
. gzip (needed to compress files during "make install")
- Available from http://gnuwin32.sourceforge.net/packages/gzip.htm.
+ Available from https://gnuwin32.sourceforge.net/packages/gzip.htm.
Each package might list other packages as prerequisites on its
download page (under "Runtime requirements"); download those as
@@ -294,7 +294,7 @@ build will run on Windows 9X and newer systems).
. Additional package (needed only if building from the repository):
Autoconf. It is available from here:
- http://sourceforge.net/projects/ezwinports/files/autoconf-2.65-msys-bin.zip/download
+ https://sourceforge.net/projects/ezwinports/files/autoconf-2.65-msys-bin.zip/download
MSYS packages are distributed as .tar.lzma compressed archives. To
install the packages manually, we recommend to use the Windows port
@@ -642,7 +642,7 @@ build will run on Windows 9X and newer systems).
To support XPM images (required for color tool-bar icons), you will
need the libXpm library. It is available from the ezwinports site,
- http://sourceforge.net/projects/ezwinports/files/ and from
+ https://sourceforge.net/projects/ezwinports/files/ and from
https://ftp.gnu.org/gnu/emacs/windows/.
For PNG images, we recommend to use versions 1.4.x and later of
@@ -665,7 +665,7 @@ build will run on Windows 9X and newer systems).
For GIF images, we recommend to use versions 5.0.0 or later of
giflib, as it is much enhanced wrt previous versions. You can find
precompiled binaries and headers for giflib on the ezwinports site,
- http://sourceforge.net/projects/ezwinports/files/ and on
+ https://sourceforge.net/projects/ezwinports/files/ and on
https://ftp.gnu.org/gnu/emacs/windows/.
Version 5.0.0 and later of giflib are binary incompatible with
@@ -689,7 +689,7 @@ build will run on Windows 9X and newer systems).
Pre-built versions of librsvg and its dependencies can be found
here:
- http://sourceforge.net/projects/ezwinports/files/
+ https://sourceforge.net/projects/ezwinports/files/
This site includes a minimal (as much as possible for librsvg)
build of the library and its dependencies; it is also more
@@ -739,7 +739,7 @@ build will run on Windows 9X and newer systems).
For WebP images you will need libwebp. You can find it here:
- http://sourceforge.net/projects/ezwinports/files/
+ https://sourceforge.net/projects/ezwinports/files/
Note: the MS-Windows binary distribution on the Google site:
@@ -779,7 +779,7 @@ build will run on Windows 9X and newer systems).
session.
You can get pre-built binaries (including any required DLL and the
- header files) at http://sourceforge.net/projects/ezwinports/files/
+ header files) at https://sourceforge.net/projects/ezwinports/files/
and on https://ftp.gnu.org/gnu/emacs/windows/.
* Optional libxml2 support
@@ -801,7 +801,7 @@ build will run on Windows 9X and newer systems).
One place where you can get pre-built Windows binaries of libxml2
(including any required DLL and the header files) is here:
- http://sourceforge.net/projects/ezwinports/files/
+ https://sourceforge.net/projects/ezwinports/files/
https://ftp.gnu.org/gnu/emacs/windows/
For runtime support of libxml2, you will also need to install the
@@ -809,7 +809,7 @@ build will run on Windows 9X and newer systems).
be available to the compiler when you compile with libxml2 support.
A MinGW port of libiconv can be found on the MinGW site:
- http://sourceforge.net/projects/mingw/files/MinGW/Base/libiconv/
+ https://sourceforge.net/projects/mingw/files/MinGW/Base/libiconv/
You need the libiconv-X.Y.Z-N-mingw32-dev.tar.lzma tarball from that
site.
diff --git a/nt/INSTALL.W64 b/nt/INSTALL.W64
index fd8f60bb0b5..9261c82db1b 100644
--- a/nt/INSTALL.W64
+++ b/nt/INSTALL.W64
@@ -19,7 +19,7 @@ Emacs with the full repository, or less if you're using a release tarball.
* Set up the MinGW-w64 / MSYS2 build environment
MinGW-w64 provides a complete runtime for projects built with GCC for 64-bit
-Windows -- it's located at http://mingw-w64.org/.
+Windows -- it's located at https://mingw-w64.org/.
MSYS2 is a Cygwin-derived software distribution for Windows which provides
build tools for MinGW-w64 -- see https://msys2.github.io/.
diff --git a/nt/Makefile.in b/nt/Makefile.in
index c904e6d451e..c5a9bf4363d 100644
--- a/nt/Makefile.in
+++ b/nt/Makefile.in
@@ -163,8 +163,8 @@ $(DESTDIR)${archlibdir}: all
@echo
@echo "Installing utilities run internally by Emacs."
umask 022; ${MKDIR_P} "$(DESTDIR)${archlibdir}"
- exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && /bin/pwd`; \
- if [ "$$exp_archlibdir" != "`/bin/pwd`" ]; then \
+ exp_archlibdir=`cd "$(DESTDIR)${archlibdir}" && pwd -P`; \
+ if [ "$$exp_archlibdir" != "`pwd -P`" ]; then \
for file in ${UTILITIES}; do \
$(INSTALL_PROGRAM) $(INSTALL_STRIP) $$file "$(DESTDIR)${archlibdir}/$$file" ; \
done ; \
diff --git a/src/ChangeLog.13 b/src/ChangeLog.13
index abf2a9421a2..268a59219c4 100644
--- a/src/ChangeLog.13
+++ b/src/ChangeLog.13
@@ -11147,7 +11147,7 @@
2013-11-01 Claudio Bley <claudio.bley@googlemail.com>
* image.c (pbm_next_char): New function.
- See http://netpbm.sourceforge.net/doc/pbm.html for the details.
+ See https://netpbm.sourceforge.net/doc/pbm.html for the details.
(pbm_scan_number): Use it.
(Qlibjpeg_version): New variable.
(syms_of_image): DEFSYM and initialize it.
@@ -14215,7 +14215,7 @@
* w32.c (PEXCEPTION_POINTERS, PEXCEPTION_RECORD, PCONTEXT): Define
variables of these types so that GDB would know about them, as aid
for debugging fatal exceptions. (Bug#15024) See also
- http://sourceware.org/ml/gdb/2013-08/msg00010.html for related
+ https://sourceware.org/ml/gdb/2013-08/msg00010.html for related
discussions.
2013-08-08 Jan Djärv <jan.h.d@swipnet.se>
diff --git a/src/bytecode.c b/src/bytecode.c
index d75767bb0c5..c765e1be2bc 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1431,7 +1431,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
NEXT;
CASE (Binteractive_p): /* Obsolete since 24.1. */
- PUSH (call0 (intern ("interactive-p")));
+ PUSH (call0 (Qinteractive_p));
NEXT;
CASE (Bforward_char):
@@ -1749,6 +1749,8 @@ get_byte_code_arity (Lisp_Object args_template)
void
syms_of_bytecode (void)
{
+ DEFSYM (Qinteractive_p, "interactive-p");
+
defsubr (&Sbyte_code);
defsubr (&Sinternal_stack_stats);
diff --git a/src/coding.c b/src/coding.c
index 0ae8eb3282b..ab73bda8440 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -12014,9 +12014,9 @@ See also the function `find-operation-coding-system'. */);
Vnetwork_coding_system_alist = Qnil;
DEFVAR_LISP ("locale-coding-system", Vlocale_coding_system,
- doc: /* Coding system to use with system messages.
-Also used for decoding keyboard input on X Window system, and for
-encoding standard output and error streams. */);
+ doc: /* Coding system to use with system messages.
+Potentially also used for decoding keyboard input on X Windows, and is
+used for encoding standard output and error streams. */);
Vlocale_coding_system = Qnil;
/* The eol mnemonics are reset in startup.el system-dependently. */
diff --git a/src/comp.c b/src/comp.c
index 4813ca04a90..b7541c5d9f7 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -68,6 +68,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#undef gcc_jit_context_get_type
#undef gcc_jit_context_new_array_access
#undef gcc_jit_context_new_array_type
+#undef gcc_jit_context_new_bitcast
#undef gcc_jit_context_new_binary_op
#undef gcc_jit_context_new_call
#undef gcc_jit_context_new_call_through_ptr
@@ -108,6 +109,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#undef gcc_jit_struct_set_fields
#undef gcc_jit_type_get_const
#undef gcc_jit_type_get_pointer
+#undef gcc_jit_type_is_pointer
#undef gcc_jit_version_major
#undef gcc_jit_version_minor
#undef gcc_jit_version_patchlevel
@@ -180,8 +182,13 @@ DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_call_through_ptr,
(gcc_jit_context *ctxt, gcc_jit_location *loc,
gcc_jit_rvalue *fn_ptr, int numargs, gcc_jit_rvalue **args));
DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_cast,
+ (gcc_jit_context * ctxt, gcc_jit_location *loc,
+ gcc_jit_rvalue *rvalue, gcc_jit_type *type));
+#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
+DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_bitcast,
(gcc_jit_context *ctxt, gcc_jit_location *loc,
gcc_jit_rvalue *rvalue, gcc_jit_type *type));
+#endif
DEF_DLL_FN (gcc_jit_rvalue *, gcc_jit_context_new_comparison,
(gcc_jit_context *ctxt, gcc_jit_location *loc,
enum gcc_jit_comparison op, gcc_jit_rvalue *a, gcc_jit_rvalue *b));
@@ -224,6 +231,9 @@ DEF_DLL_FN (gcc_jit_type *, gcc_jit_struct_as_type,
(gcc_jit_struct *struct_type));
DEF_DLL_FN (gcc_jit_type *, gcc_jit_type_get_const, (gcc_jit_type *type));
DEF_DLL_FN (gcc_jit_type *, gcc_jit_type_get_pointer, (gcc_jit_type *type));
+#ifdef LIBGCCJIT_HAVE_REFLECTION
+DEF_DLL_FN (gcc_jit_type *, gcc_jit_type_is_pointer, (gcc_jit_type *type));
+#endif
DEF_DLL_FN (void, gcc_jit_block_add_assignment,
(gcc_jit_block *block, gcc_jit_location *loc, gcc_jit_lvalue *lvalue,
gcc_jit_rvalue *rvalue));
@@ -293,6 +303,9 @@ init_gccjit_functions (void)
LOAD_DLL_FN (library, gcc_jit_context_get_type);
LOAD_DLL_FN (library, gcc_jit_context_new_array_access);
LOAD_DLL_FN (library, gcc_jit_context_new_array_type);
+#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
+ LOAD_DLL_FN (library, gcc_jit_context_new_bitcast);
+#endif
LOAD_DLL_FN (library, gcc_jit_context_new_binary_op);
LOAD_DLL_FN (library, gcc_jit_context_new_call);
LOAD_DLL_FN (library, gcc_jit_context_new_call_through_ptr);
@@ -334,6 +347,9 @@ init_gccjit_functions (void)
LOAD_DLL_FN (library, gcc_jit_struct_set_fields);
LOAD_DLL_FN (library, gcc_jit_type_get_const);
LOAD_DLL_FN (library, gcc_jit_type_get_pointer);
+#ifdef LIBGCCJIT_HAVE_REFLECTION
+ LOAD_DLL_FN (library, gcc_jit_type_is_pointer);
+#endif
LOAD_DLL_FN_OPT (library, gcc_jit_context_add_command_line_option);
LOAD_DLL_FN_OPT (library, gcc_jit_context_add_driver_option);
#if defined (LIBGCCJIT_HAVE_gcc_jit_global_set_initializer)
@@ -368,6 +384,9 @@ init_gccjit_functions (void)
#define gcc_jit_context_get_type fn_gcc_jit_context_get_type
#define gcc_jit_context_new_array_access fn_gcc_jit_context_new_array_access
#define gcc_jit_context_new_array_type fn_gcc_jit_context_new_array_type
+#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
+# define gcc_jit_context_new_bitcast fn_gcc_jit_context_new_bitcast
+#endif
#define gcc_jit_context_new_binary_op fn_gcc_jit_context_new_binary_op
#define gcc_jit_context_new_call fn_gcc_jit_context_new_call
#define gcc_jit_context_new_call_through_ptr fn_gcc_jit_context_new_call_through_ptr
@@ -410,6 +429,9 @@ init_gccjit_functions (void)
#define gcc_jit_rvalue_get_type fn_gcc_jit_rvalue_get_type
#define gcc_jit_struct_as_type fn_gcc_jit_struct_as_type
#define gcc_jit_struct_set_fields fn_gcc_jit_struct_set_fields
+#ifdef LIBGCCJIT_HAVE_REFLECTION
+# define gcc_jit_type_is_pointer fn_gcc_jit_type_is_pointer
+#endif
#define gcc_jit_type_get_const fn_gcc_jit_type_get_const
#define gcc_jit_type_get_pointer fn_gcc_jit_type_get_pointer
#if defined (LIBGCCJIT_HAVE_gcc_jit_version)
@@ -518,7 +540,9 @@ typedef struct {
static f_reloc_t freloc;
-#define NUM_CAST_TYPES 15
+#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
+# define NUM_CAST_TYPES 15
+#endif
typedef struct {
EMACS_INT len;
@@ -593,13 +617,15 @@ typedef struct {
gcc_jit_rvalue *current_thread_ref;
/* Other globals. */
gcc_jit_rvalue *pure_ptr;
- /* libgccjit has really limited support for casting therefore this union will
- be used for the scope. */
+#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
+ /* This version of libgccjit has really limited support for casting
+ therefore this union will be used for the scope. */
gcc_jit_type *cast_union_type;
gcc_jit_function *cast_functions_from_to[NUM_CAST_TYPES][NUM_CAST_TYPES];
gcc_jit_function *cast_ptr_to_int;
gcc_jit_function *cast_int_to_ptr;
gcc_jit_type *cast_types[NUM_CAST_TYPES];
+#endif
gcc_jit_function *func; /* Current function being compiled. */
bool func_has_non_local; /* From comp-func has-non-local slot. */
EMACS_INT func_speed; /* From comp-func speed slot. */
@@ -1100,6 +1126,7 @@ emit_cond_jump (gcc_jit_rvalue *test,
}
+#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
static int
type_to_cast_index (gcc_jit_type * type)
{
@@ -1109,6 +1136,7 @@ type_to_cast_index (gcc_jit_type * type)
xsignal1 (Qnative_ice, build_string ("unsupported cast"));
}
+#endif
static gcc_jit_rvalue *
emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
@@ -1145,14 +1173,48 @@ emit_coerce (gcc_jit_type *new_type, gcc_jit_rvalue *obj)
}
#endif
+#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
+ bool old_is_ptr = gcc_jit_type_is_pointer (old_type) != NULL;
+ bool new_is_ptr = gcc_jit_type_is_pointer (new_type) != NULL;
+
+ gcc_jit_rvalue *tmp = obj;
+
+ /* `gcc_jit_context_new_bitcast` requires that the types being converted
+ between have the same layout and as such, doesn't allow converting
+ between an arbitrarily sized integer/boolean and a pointer. Casting it
+ to a uintptr/void* is still necessary, to ensure that it can be bitcast
+ into a (void *)/uintptr respectively. */
+ if (old_is_ptr != new_is_ptr)
+ {
+ if (old_is_ptr)
+ {
+ tmp = gcc_jit_context_new_cast (comp.ctxt, NULL, tmp,
+ comp.void_ptr_type);
+ tmp = gcc_jit_context_new_bitcast (comp.ctxt, NULL, tmp,
+ comp.uintptr_type);
+ }
+ else
+ {
+ tmp = gcc_jit_context_new_cast (comp.ctxt, NULL, tmp,
+ comp.uintptr_type);
+ tmp = gcc_jit_context_new_bitcast (comp.ctxt, NULL, tmp,
+ comp.void_ptr_type);
+ }
+ }
+ return gcc_jit_context_new_cast (comp.ctxt, NULL, tmp, new_type);
+
+#else /* !LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast */
+
int old_index = type_to_cast_index (old_type);
int new_index = type_to_cast_index (new_type);
/* Lookup the appropriate cast function in the cast matrix. */
return gcc_jit_context_new_call (comp.ctxt,
- NULL,
- comp.cast_functions_from_to[old_index][new_index],
- 1, &obj);
+ NULL,
+ comp.cast_functions_from_to
+ [old_index][new_index],
+ 1, &obj);
+#endif
}
static gcc_jit_rvalue *
@@ -3318,6 +3380,7 @@ define_thread_state_struct (void)
gcc_jit_type_get_pointer (gcc_jit_struct_as_type (comp.thread_state_s));
}
+#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
static gcc_jit_function *
define_type_punning (const char *name,
gcc_jit_type *from, gcc_jit_field *from_field,
@@ -3451,6 +3514,7 @@ define_cast_functions (void)
comp.void_ptr_type,
cast_union_fields[0]);
+
for (int i = 0; i < NUM_CAST_TYPES; ++i)
comp.cast_types[i] = cast_types[i].type;
@@ -3460,6 +3524,7 @@ define_cast_functions (void)
comp.cast_functions_from_to[i][j] =
define_cast_from_to (cast_types[i], cast_types[j]);
}
+#endif /* !LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast */
static void
define_CHECK_TYPE (void)
@@ -4660,7 +4725,9 @@ Return t on success. */)
define_jmp_buf ();
define_handler_struct ();
define_thread_state_struct ();
+#ifndef LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
define_cast_functions ();
+#endif
return Qt;
}
@@ -5107,6 +5174,7 @@ maybe_defer_native_compilation (Lisp_Object function_name,
return;
if (!native_comp_deferred_compilation
+ || !NILP (Vinhibit_automatic_native_compilation)
|| noninteractive
|| !NILP (Vpurify_flag)
|| !COMPILEDP (definition)
@@ -5610,6 +5678,14 @@ For internal use. */);
doc: /* Non-nil when comp.el can be native compiled.
For internal use. */);
/* Compiler control customizes. */
+ DEFVAR_LISP ("inhibit-automatic-native-compilation",
+ Vinhibit_automatic_native_compilation,
+ doc: /* If non-nil, inhibit automatic native compilation of loaded .elc files.
+
+After compilation, each function definition is updated to the native
+compiled one. */);
+ Vinhibit_automatic_native_compilation = Qnil;
+
DEFVAR_BOOL ("native-comp-deferred-compilation",
native_comp_deferred_compilation,
doc: /* If non-nil compile loaded .elc files asynchronously.
diff --git a/src/composite.c b/src/composite.c
index 22422cca090..6b256171ac7 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -800,6 +800,53 @@ composition_gstring_width (Lisp_Object gstring, ptrdiff_t from, ptrdiff_t to,
return width;
}
+/* Adjust the width of each grapheme cluster of GSTRING because
+ zero-width grapheme clusters are not displayed. If the width is
+ zero, then the width of the last glyph in the cluster is
+ incremented. */
+
+void
+composition_gstring_adjust_zero_width (Lisp_Object gstring)
+{
+ ptrdiff_t from = 0;
+ int width = 0;
+
+ for (ptrdiff_t i = 0; ; i++)
+ {
+ Lisp_Object glyph;
+
+ if (i < LGSTRING_GLYPH_LEN (gstring))
+ glyph = LGSTRING_GLYPH (gstring, i);
+ else
+ glyph = Qnil;
+
+ if (NILP (glyph) || from != LGLYPH_FROM (glyph))
+ {
+ eassert (i > 0);
+ Lisp_Object last = LGSTRING_GLYPH (gstring, i - 1);
+
+ if (width == 0)
+ {
+ if (NILP (LGLYPH_ADJUSTMENT (last)))
+ LGLYPH_SET_ADJUSTMENT (last,
+ CALLN (Fvector,
+ make_fixnum (0), make_fixnum (0),
+ make_fixnum (LGLYPH_WIDTH (last)
+ + 1)));
+ else
+ ASET (LGLYPH_ADJUSTMENT (last), 2,
+ make_fixnum (LGLYPH_WADJUST (last) + 1));
+ }
+ if (NILP (glyph))
+ break;
+ from = LGLYPH_FROM (glyph);
+ width = 0;
+ }
+ width += (NILP (LGLYPH_ADJUSTMENT (glyph))
+ ? LGLYPH_WIDTH (glyph) : LGLYPH_WADJUST (glyph));
+ }
+}
+
static Lisp_Object gstring_work;
static Lisp_Object gstring_work_headers;
@@ -876,7 +923,8 @@ fill_gstring_body (Lisp_Object gstring)
}
LGLYPH_SET_ADJUSTMENT (g, Qnil);
}
- if (i < LGSTRING_GLYPH_LEN (gstring))
+ len = LGSTRING_GLYPH_LEN (gstring);
+ for (; i < len; i++)
LGSTRING_SET_GLYPH (gstring, i, Qnil);
}
diff --git a/src/composite.h b/src/composite.h
index d77dd0d5062..8a6fd203d09 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -340,6 +340,7 @@ extern Lisp_Object composition_gstring_from_id (ptrdiff_t);
extern bool composition_gstring_p (Lisp_Object);
extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t,
struct font_metrics *);
+extern void composition_gstring_adjust_zero_width (Lisp_Object);
extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t,
ptrdiff_t *, ptrdiff_t *,
diff --git a/src/conf_post.h b/src/conf_post.h
index 6ecebf36ab9..fb8d2e5d96e 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -30,14 +30,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#endif
/* To help make dependencies clearer elsewhere, this file typically
- does not #include other files. The exceptions are stdbool.h
- because it is unlikely to interfere with configuration and bool is
- such a core part of the C language, and ms-w32.h (DOS_NT
+ does not #include other files. The exception is ms-w32.h (DOS_NT
only) because it historically was included here and changing that
would take some work. */
-#include <stdbool.h>
-
#if defined WINDOWSNT && !defined DEFER_MS_W32_H
# include <ms-w32.h>
#endif
diff --git a/src/data.c b/src/data.c
index b19e10582e5..221a6f58835 100644
--- a/src/data.c
+++ b/src/data.c
@@ -4124,6 +4124,7 @@ syms_of_data (void)
DEFSYM (Qsymbolp, "symbolp");
DEFSYM (Qfixnump, "fixnump");
DEFSYM (Qintegerp, "integerp");
+ DEFSYM (Qbooleanp, "booleanp");
DEFSYM (Qnatnump, "natnump");
DEFSYM (Qwholenump, "wholenump");
DEFSYM (Qstringp, "stringp");
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 943a4aff8e7..1c74180f15c 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -398,7 +398,7 @@ xd_signature (char *signature, int dtype, int parent_type, Lisp_Object object)
case DBUS_TYPE_BOOLEAN:
/* There must be an argument. */
if (EQ (QCboolean, object))
- wrong_type_argument (intern ("booleanp"), object);
+ wrong_type_argument (Qbooleanp, object);
sprintf (signature, "%c", dtype);
break;
@@ -649,7 +649,7 @@ xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter)
case DBUS_TYPE_BOOLEAN:
/* There must be an argument. */
if (EQ (QCboolean, object))
- wrong_type_argument (intern ("booleanp"), object);
+ wrong_type_argument (Qbooleanp, object);
{
dbus_bool_t val = (NILP (object)) ? FALSE : TRUE;
XD_DEBUG_MESSAGE ("%c %s", dtype, (val == FALSE) ? "false" : "true");
diff --git a/src/dired.c b/src/dired.c
index c2c099f0a5f..ef729df5d2b 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -923,11 +923,12 @@ Elements of the attribute list are:
8. File modes, as a string of ten letters or dashes as in ls -l.
9. An unspecified value, present only for backward compatibility.
10. inode number, as a nonnegative integer.
-11. Filesystem device number, as an integer.
+11. Filesystem device identifier, as an integer or a cons cell of integers.
Large integers are bignums, so `eq' might not work on them.
On most filesystems, the combination of the inode and the device
-number uniquely identifies the file.
+identifier uniquely identifies the file. This unique file identification
+is provided by the access function `file-attribute-file-identifier'.
On MS-Windows, performance depends on `w32-get-true-file-attributes',
which see.
diff --git a/src/dispnew.c b/src/dispnew.c
index 8932f103f1f..2568ba1086a 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -1810,9 +1810,12 @@ allocate_matrices_for_window_redisplay (struct window *w)
if (w->desired_matrix == NULL)
{
w->desired_matrix = new_glyph_matrix (NULL);
- w->current_matrix = new_glyph_matrix (NULL);
+ eassert (w->current_matrix == NULL);
}
+ if (w->current_matrix == NULL)
+ w->current_matrix = new_glyph_matrix (NULL);
+
dim.width = required_matrix_width (w);
dim.height = required_matrix_height (w);
adjust_glyph_matrix (w, w->desired_matrix, 0, 0, dim);
@@ -4929,7 +4932,9 @@ update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p,
{
if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
{
- if (FRAME_TERMCAP_P (f))
+ /* Note that output_buffer_size being 0 means that we want the
+ old default behavior of flushing output every now and then. */
+ if (FRAME_TERMCAP_P (f) && FRAME_TTY (f)->output_buffer_size == 0)
{
/* Flush out every so many lines.
Also flush out if likely to have more than 1k buffered
diff --git a/src/doc.c b/src/doc.c
index d98d121ebd5..67a5f845b93 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -342,7 +342,7 @@ string is passed through `substitute-command-keys'. */)
doc = module_function_documentation (XMODULE_FUNCTION (fun));
#endif
else
- doc = call1 (intern ("function-documentation"), fun);
+ doc = call1 (Qfunction_documentation, fun);
/* If DOC is 0, it's typically because of a dumped file missing
from the DOC file (bug in src/Makefile.in). */
diff --git a/src/dynlib.h b/src/dynlib.h
index 03b8f983564..9a11c128981 100644
--- a/src/dynlib.h
+++ b/src/dynlib.h
@@ -21,7 +21,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define DYNLIB_H
#include <attribute.h>
-#include <stdbool.h>
typedef void *dynlib_handle_ptr;
dynlib_handle_ptr dynlib_open (const char *path);
diff --git a/src/editfns.c b/src/editfns.c
index b774e79337f..3f9618edb08 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3551,8 +3551,15 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
|| float_conversion || conversion == 'i'
|| conversion == 'o' || conversion == 'x'
|| conversion == 'X'))
- error ("Invalid format operation %%%c",
- STRING_CHAR ((unsigned char *) format - 1));
+ {
+ unsigned char *p = (unsigned char *) format - 1;
+ if (multibyte_format)
+ error ("Invalid format operation %%%c", STRING_CHAR (p));
+ else
+ error (*p <= 127 ? "Invalid format operation %%%c"
+ : "Invalid format operation char #o%03o",
+ *p);
+ }
else if (! (FIXNUMP (arg) || ((BIGNUMP (arg) || FLOATP (arg))
&& conversion != 'c')))
error ("Format specifier doesn't match argument type");
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 1c392d65df8..fcdf103c19b 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -78,7 +78,6 @@ To add a new module function, proceed as follows:
#include "emacs-module.h"
#include <stdarg.h>
-#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/src/emacs-module.h.in b/src/emacs-module.h.in
index 6642b55d932..bef89b059fc 100644
--- a/src/emacs-module.h.in
+++ b/src/emacs-module.h.in
@@ -30,7 +30,8 @@ information how to write modules and use this header file.
#include <stdint.h>
#include <time.h>
-#ifndef __cplusplus
+#if ((defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 202311 \
+ && !defined __bool_true_false_are_defined && !defined __cplusplus)
#include <stdbool.h>
#endif
diff --git a/src/emacs.c b/src/emacs.c
index 3c768412818..43e81b912c6 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -299,7 +299,7 @@ Initialization options:\n\
-x to be used in #!/usr/bin/emacs -x\n\
and has approximately the same meaning\n\
as -Q --script\n\
---terminal, -t DEVICE use DEVICE for terminal I/O\n \
+--terminal, -t DEVICE use DEVICE for terminal I/O\n\
--user, -u USER load ~USER/.emacs instead of your own\n\
\n\
",
@@ -891,19 +891,17 @@ load_pdump (int argc, char **argv)
}
/* Where's our executable? */
- ptrdiff_t bufsize;
-#ifndef NS_SELF_CONTAINED
- ptrdiff_t exec_bufsize;
-#endif
- emacs_executable = find_emacs_executable (argv[0], &bufsize);
-#ifndef NS_SELF_CONTAINED
- exec_bufsize = bufsize;
-#endif
+ ptrdiff_t exec_bufsize, bufsize, needed;
+ emacs_executable = find_emacs_executable (argv[0], &exec_bufsize);
/* If we couldn't find our executable, go straight to looking for
the dump in the hardcoded location. */
if (!(emacs_executable && *emacs_executable))
- goto hardcoded;
+ {
+ bufsize = 0;
+ dump_file = NULL;
+ goto hardcoded;
+ }
if (dump_file)
{
@@ -931,8 +929,8 @@ load_pdump (int argc, char **argv)
strip_suffix_length))
exenamelen = prefix_length;
}
- ptrdiff_t needed = exenamelen + strlen (suffix) + 1;
- dump_file = xpalloc (NULL, &bufsize, needed - bufsize, -1, 1);
+ bufsize = exenamelen + strlen (suffix) + 1;
+ dump_file = xpalloc (NULL, &bufsize, 1, -1, 1);
memcpy (dump_file, emacs_executable, exenamelen);
strcpy (dump_file + exenamelen, suffix);
result = pdumper_load (dump_file, emacs_executable);
diff --git a/src/eval.c b/src/eval.c
index 56b42966623..8810136c041 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -211,15 +211,8 @@ backtrace_thread_next (struct thread_state *tstate, union specbinding *pdl)
void
init_eval_once (void)
{
- /* Don't forget to update docs (lispref node "Local Variables"). */
-#ifndef HAVE_NATIVE_COMP
- max_specpdl_size = 1800; /* See bug#46818. */
- max_lisp_eval_depth = 800;
-#else
- /* Original values increased for comp.el. */
- max_specpdl_size = 2500;
+ /* Don't forget to update docs (lispref node "Eval"). */
max_lisp_eval_depth = 1600;
-#endif
Vrun_hooks = Qnil;
pdumper_do_now_and_after_load (init_eval_once_for_pdumper);
}
@@ -270,8 +263,7 @@ max_ensure_room (intmax_t *m, intmax_t a, intmax_t b)
static void
restore_stack_limits (Lisp_Object data)
{
- integer_to_intmax (XCAR (data), &max_specpdl_size);
- integer_to_intmax (XCDR (data), &max_lisp_eval_depth);
+ integer_to_intmax (data, &max_lisp_eval_depth);
}
/* Call the Lisp debugger, giving it argument ARG. */
@@ -283,9 +275,6 @@ call_debugger (Lisp_Object arg)
specpdl_ref count = SPECPDL_INDEX ();
Lisp_Object val;
intmax_t old_depth = max_lisp_eval_depth;
- /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */
- ptrdiff_t counti = specpdl_ref_to_count (count);
- intmax_t old_max = max (max_specpdl_size, counti);
/* The previous value of 40 is too small now that the debugger
prints using cl-prin1 instead of prin1. Printing lists nested 8
@@ -293,20 +282,8 @@ call_debugger (Lisp_Object arg)
currently requires 77 additional frames. See bug#31919. */
max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
- /* While debugging Bug#16603, previous value of 100 was found
- too small to avoid specpdl overflow in the debugger itself. */
- max_ensure_room (&max_specpdl_size, counti, 200);
-
- if (old_max == counti)
- {
- /* We can enter the debugger due to specpdl overflow (Bug#16603). */
- specpdl_ptr--;
- grow_specpdl ();
- }
-
/* Restore limits after leaving the debugger. */
- record_unwind_protect (restore_stack_limits,
- Fcons (make_int (old_max), make_int (old_depth)));
+ record_unwind_protect (restore_stack_limits, make_int (old_depth));
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
@@ -938,12 +915,9 @@ usage: (let* VARLIST BODY...) */)
lexenv = Vinternal_interpreter_environment;
Lisp_Object varlist = XCAR (args);
- while (CONSP (varlist))
+ FOR_EACH_TAIL (varlist)
{
- maybe_quit ();
-
elt = XCAR (varlist);
- varlist = XCDR (varlist);
if (SYMBOLP (elt))
{
var = elt;
@@ -1677,10 +1651,12 @@ process_quit_flag (void)
void
probably_quit (void)
{
+ specpdl_ref gc_count = inhibit_garbage_collection ();
if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
process_quit_flag ();
else if (pending_signals)
process_pending_signals ();
+ unbind_to (gc_count, Qnil);
}
DEFUN ("signal", Fsignal, Ssignal, 2, 2, 0,
@@ -1757,8 +1733,6 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
{
/* Edebug takes care of restoring these variables when it exits. */
max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20);
- ptrdiff_t counti = specpdl_ref_to_count (SPECPDL_INDEX ());
- max_ensure_room (&max_specpdl_size, counti, 40);
call2 (Vsignal_hook_function, error_symbol, data);
}
@@ -1827,8 +1801,6 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
{
max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
specpdl_ref count = SPECPDL_INDEX ();
- ptrdiff_t counti = specpdl_ref_to_count (count);
- max_ensure_room (&max_specpdl_size, counti, 200);
specbind (Qdebugger, Qdebug_early);
call_debugger (list2 (Qerror, Fcons (error_symbol, data)));
unbind_to (count, Qnil);
@@ -1844,12 +1816,10 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
{
max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
specpdl_ref count = SPECPDL_INDEX ();
- ptrdiff_t counti = specpdl_ref_to_count (count);
AUTO_STRING (redisplay_trace, "*Redisplay_trace*");
Lisp_Object redisplay_trace_buffer;
AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */
Lisp_Object delayed_warning;
- max_ensure_room (&max_specpdl_size, counti, 200);
redisplay_trace_buffer = Fget_buffer_create (redisplay_trace, Qnil);
current_buffer = XBUFFER (redisplay_trace_buffer);
if (!backtrace_yet) /* Are we on the first backtrace of the command? */
@@ -2381,17 +2351,12 @@ grow_specpdl_allocation (void)
eassert (specpdl_ptr == specpdl_end);
specpdl_ref count = SPECPDL_INDEX ();
- ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000);
+ ptrdiff_t max_size = PTRDIFF_MAX - 1000;
union specbinding *pdlvec = specpdl - 1;
ptrdiff_t size = specpdl_end - specpdl;
ptrdiff_t pdlvecsize = size + 1;
if (max_size <= size)
- {
- if (max_specpdl_size < 400)
- max_size = max_specpdl_size = 400;
- if (max_size <= size)
- xsignal0 (Qexcessive_variable_binding);
- }
+ xsignal0 (Qexcessive_variable_binding); /* Can't happen, essentially. */
pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl);
specpdl = pdlvec + 1;
specpdl_end = specpdl + pdlvecsize - 1;
@@ -4234,22 +4199,6 @@ Lisp_Object backtrace_top_function (void)
void
syms_of_eval (void)
{
- DEFVAR_INT ("max-specpdl-size", max_specpdl_size,
- doc: /* Limit on number of Lisp variable bindings and `unwind-protect's.
-
-If Lisp code tries to use more bindings than this amount, an error is
-signaled.
-
-You can safely increase this variable substantially if the default
-value proves inconveniently small. However, if you increase it too
-much, Emacs could run out of memory trying to make the stack bigger.
-Note that this limit may be silently increased by the debugger if
-`debug-on-error' or `debug-on-quit' is set.
-
-\"spec\" is short for \"special variables\", i.e., dynamically bound
-variables. \"PDL\" is short for \"push-down list\", which is an old
-term for \"stack\". */);
-
DEFVAR_INT ("max-lisp-eval-depth", max_lisp_eval_depth,
doc: /* Limit on depth in `eval', `apply' and `funcall' before error.
diff --git a/src/fileio.c b/src/fileio.c
index 9697f6c8cf1..8f96e973b25 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3808,7 +3808,7 @@ file_offset (Lisp_Object val)
}
}
- wrong_type_argument (intern ("file-offset"), val);
+ wrong_type_argument (Qfile_offset, val);
}
/* Return a special time value indicating the error number ERRNUM. */
@@ -4875,7 +4875,7 @@ by calling `format-decode', which see. */)
if (! NILP (insval))
{
if (! RANGED_FIXNUMP (0, insval, ZV - PT))
- wrong_type_argument (intern ("inserted-chars"), insval);
+ wrong_type_argument (Qinserted_chars, insval);
inserted = XFIXNAT (insval);
}
}
@@ -4898,7 +4898,7 @@ by calling `format-decode', which see. */)
insval = call3 (Qformat_decode,
Qnil, make_fixnum (inserted), visit);
if (! RANGED_FIXNUMP (0, insval, ZV - PT))
- wrong_type_argument (intern ("inserted-chars"), insval);
+ wrong_type_argument (Qinserted_chars, insval);
inserted = XFIXNAT (insval);
}
else
@@ -4921,7 +4921,7 @@ by calling `format-decode', which see. */)
insval = call3 (Qformat_decode,
Qnil, make_fixnum (oinserted), visit);
if (! RANGED_FIXNUMP (0, insval, ZV - PT))
- wrong_type_argument (intern ("inserted-chars"), insval);
+ wrong_type_argument (Qinserted_chars, insval);
if (ochars_modiff == CHARS_MODIFF)
/* format_decode didn't modify buffer's characters => move
point back to position before inserted text and leave
@@ -4944,7 +4944,7 @@ by calling `format-decode', which see. */)
if (!NILP (insval))
{
if (! RANGED_FIXNUMP (0, insval, ZV - PT))
- wrong_type_argument (intern ("inserted-chars"), insval);
+ wrong_type_argument (Qinserted_chars, insval);
inserted = XFIXNAT (insval);
}
}
@@ -4962,7 +4962,7 @@ by calling `format-decode', which see. */)
if (!NILP (insval))
{
if (! RANGED_FIXNUMP (0, insval, ZV - PT))
- wrong_type_argument (intern ("inserted-chars"), insval);
+ wrong_type_argument (Qinserted_chars, insval);
if (ochars_modiff == CHARS_MODIFF)
/* after_insert_file_functions didn't modify
buffer's characters => move point back to
@@ -5000,9 +5000,10 @@ by calling `format-decode', which see. */)
unbind_to (count1, Qnil);
}
- if (!NILP (visit) && current_buffer->modtime.tv_nsec < 0)
+ if (save_errno != 0)
{
/* Signal an error if visiting a file that could not be opened. */
+ eassert (!NILP (visit) && NILP (handler));
report_file_errno ("Opening input file", orig_filename, save_errno);
}
@@ -6019,11 +6020,6 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
bool old_message_p = 0;
struct auto_save_unwind auto_save_unwind;
- intmax_t sum = INT_ADD_WRAPV (specpdl_end - specpdl, 40, &sum)
- ? INTMAX_MAX : sum;
- if (max_specpdl_size < sum)
- max_specpdl_size = sum;
-
if (minibuf_level)
no_message = Qt;
@@ -6367,7 +6363,7 @@ init_fileio (void)
For more on why fsync does not suffice even if it works properly, see:
Roche X. Necessary step(s) to synchronize filename operations on disk.
Austin Group Defect 672, 2013-03-19
- http://austingroupbugs.net/view.php?id=672 */
+ https://austingroupbugs.net/view.php?id=672 */
write_region_inhibit_fsync = noninteractive;
}
@@ -6431,9 +6427,11 @@ syms_of_fileio (void)
DEFSYM (Qfile_date_error, "file-date-error");
DEFSYM (Qfile_missing, "file-missing");
DEFSYM (Qpermission_denied, "permission-denied");
+ DEFSYM (Qfile_offset, "file-offset");
DEFSYM (Qfile_notify_error, "file-notify-error");
DEFSYM (Qremote_file_error, "remote-file-error");
DEFSYM (Qexcl, "excl");
+ DEFSYM (Qinserted_chars, "inserted-chars");
DEFVAR_LISP ("file-name-coding-system", Vfile_name_coding_system,
doc: /* Coding system for encoding file names.
diff --git a/src/fns.c b/src/fns.c
index 2f4808be3d0..40557923827 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -433,6 +433,22 @@ If string STR1 is greater, the value is a positive number N;
return Qt;
}
+/* Check whether the platform allows access to unaligned addresses for
+ size_t integers without trapping or undue penalty (a few cycles is OK).
+
+ This whitelist is incomplete but since it is only used to improve
+ performance, omitting cases is safe. */
+#if defined __x86_64__|| defined __amd64__ \
+ || defined __i386__ || defined __i386 \
+ || defined __arm64__ || defined __aarch64__ \
+ || defined __powerpc__ || defined __powerpc \
+ || defined __ppc__ || defined __ppc \
+ || defined __s390__ || defined __s390x__
+#define HAVE_FAST_UNALIGNED_ACCESS 1
+#else
+#define HAVE_FAST_UNALIGNED_ACCESS 0
+#endif
+
DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
doc: /* Return non-nil if STRING1 is less than STRING2 in lexicographic order.
Case is significant.
@@ -449,25 +465,87 @@ Symbols are also allowed; their print names are used instead. */)
CHECK_STRING (string2);
ptrdiff_t n = min (SCHARS (string1), SCHARS (string2));
- if (!STRING_MULTIBYTE (string1) && !STRING_MULTIBYTE (string2))
+
+ if ((!STRING_MULTIBYTE (string1) || SCHARS (string1) == SBYTES (string1))
+ && (!STRING_MULTIBYTE (string2) || SCHARS (string2) == SBYTES (string2)))
{
- /* Both arguments are unibyte (hot path). */
+ /* Each argument is either unibyte or all-ASCII multibyte:
+ we can compare bytewise. */
int d = memcmp (SSDATA (string1), SSDATA (string2), n);
return d < 0 || (d == 0 && n < SCHARS (string2)) ? Qt : Qnil;
}
+ else if (STRING_MULTIBYTE (string1) && STRING_MULTIBYTE (string2))
+ {
+ /* Two arbitrary multibyte strings: we cannot use memcmp because
+ the encoding for raw bytes would sort those between U+007F and U+0080
+ which isn't where we want them.
+ Instead, we skip the longest common prefix and look at
+ what follows. */
+ ptrdiff_t nb1 = SBYTES (string1);
+ ptrdiff_t nb2 = SBYTES (string2);
+ ptrdiff_t nb = min (nb1, nb2);
+ ptrdiff_t b = 0;
+
+ /* String data is normally allocated with word alignment, but
+ there are exceptions (notably pure strings) so we restrict the
+ wordwise skipping to safe architectures. */
+ if (HAVE_FAST_UNALIGNED_ACCESS)
+ {
+ /* First compare entire machine words. */
+ typedef size_t word_t;
+ int ws = sizeof (word_t);
+ const word_t *w1 = (const word_t *) SDATA (string1);
+ const word_t *w2 = (const word_t *) SDATA (string2);
+ while (b < nb - ws + 1 && w1[b / ws] == w2[b / ws])
+ b += ws;
+ }
- ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0, i2_byte = 0;
-
- while (i1 < n)
+ /* Scan forward to the differing byte. */
+ while (b < nb && SREF (string1, b) == SREF (string2, b))
+ b++;
+
+ if (b >= nb)
+ /* One string is a prefix of the other. */
+ return b < nb2 ? Qt : Qnil;
+
+ /* Now back up to the start of the differing characters:
+ it's the last byte not having the bit pattern 10xxxxxx. */
+ while ((SREF (string1, b) & 0xc0) == 0x80)
+ b--;
+
+ /* Compare the differing characters. */
+ ptrdiff_t i1 = 0, i2 = 0;
+ ptrdiff_t i1_byte = b, i2_byte = b;
+ int c1 = fetch_string_char_advance_no_check (string1, &i1, &i1_byte);
+ int c2 = fetch_string_char_advance_no_check (string2, &i2, &i2_byte);
+ return c1 < c2 ? Qt : Qnil;
+ }
+ else if (STRING_MULTIBYTE (string1))
{
- /* When we find a mismatch, we must compare the
- characters, not just the bytes. */
- int c1 = fetch_string_char_advance (string1, &i1, &i1_byte);
- int c2 = fetch_string_char_advance (string2, &i2, &i2_byte);
- if (c1 != c2)
- return c1 < c2 ? Qt : Qnil;
+ /* string1 multibyte, string2 unibyte */
+ ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0;
+ while (i1 < n)
+ {
+ int c1 = fetch_string_char_advance_no_check (string1, &i1, &i1_byte);
+ int c2 = SREF (string2, i2++);
+ if (c1 != c2)
+ return c1 < c2 ? Qt : Qnil;
+ }
+ return i1 < SCHARS (string2) ? Qt : Qnil;
+ }
+ else
+ {
+ /* string1 unibyte, string2 multibyte */
+ ptrdiff_t i1 = 0, i2 = 0, i2_byte = 0;
+ while (i1 < n)
+ {
+ int c1 = SREF (string1, i1++);
+ int c2 = fetch_string_char_advance_no_check (string2, &i2, &i2_byte);
+ if (c1 != c2)
+ return c1 < c2 ? Qt : Qnil;
+ }
+ return i1 < SCHARS (string2) ? Qt : Qnil;
}
- return i1 < SCHARS (string2) ? Qt : Qnil;
}
DEFUN ("string-version-lessp", Fstring_version_lessp,
@@ -610,7 +688,10 @@ DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
doc: /* Concatenate all the arguments and make the result a list.
The result is a list whose elements are the elements of all the arguments.
Each argument may be a list, vector or string.
-The last argument is not copied, just used as the tail of the new list.
+
+All arguments except the last argument are copied. The last argument
+is just used as the tail of the new list.
+
usage: (append &rest SEQUENCES) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
@@ -1412,6 +1493,7 @@ are shared, however.
Elements of ALIST that are not conses are also shared. */)
(Lisp_Object alist)
{
+ CHECK_LIST (alist);
if (NILP (alist))
return alist;
alist = Fcopy_sequence (alist);
@@ -2930,15 +3012,37 @@ FUNCTION must be a function of one argument, and must return a value
return empty_unibyte_string;
Lisp_Object *args;
SAFE_ALLOCA_LISP (args, args_alloc);
+ if (EQ (function, Qidentity))
+ {
+ /* Fast path when no function call is necessary. */
+ if (CONSP (sequence))
+ {
+ Lisp_Object src = sequence;
+ Lisp_Object *dst = args;
+ do
+ {
+ *dst++ = XCAR (src);
+ src = XCDR (src);
+ }
+ while (!NILP (src));
+ goto concat;
+ }
+ else if (VECTORP (sequence))
+ {
+ memcpy (args, XVECTOR (sequence)->contents, leni * sizeof *args);
+ goto concat;
+ }
+ }
ptrdiff_t nmapped = mapcar1 (leni, args, function, sequence);
- ptrdiff_t nargs = 2 * nmapped - 1;
eassert (nmapped == leni);
+ concat: ;
+ ptrdiff_t nargs = args_alloc;
if (NILP (separator) || (STRINGP (separator) && SCHARS (separator) == 0))
- nargs = nmapped;
+ nargs = leni;
else
{
- for (ptrdiff_t i = nmapped - 1; i > 0; i--)
+ for (ptrdiff_t i = leni - 1; i > 0; i--)
args[i + i] = args[i];
for (ptrdiff_t i = 1; i < nargs; i += 2)
diff --git a/src/font.c b/src/font.c
index 8acedb9bf88..6e720bc2856 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1836,296 +1836,6 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec
}
-/* This part (through the next ^L) is still experimental and not
- tested much. We may drastically change codes. */
-
-/* OTF handler. */
-
-#if 0
-
-#define LGSTRING_HEADER_SIZE 6
-#define LGSTRING_GLYPH_SIZE 8
-
-static int
-check_gstring (Lisp_Object gstring)
-{
- Lisp_Object val;
- ptrdiff_t i;
- int j;
-
- CHECK_VECTOR (gstring);
- val = AREF (gstring, 0);
- CHECK_VECTOR (val);
- if (ASIZE (val) < LGSTRING_HEADER_SIZE)
- goto err;
- CHECK_FONT_OBJECT (LGSTRING_FONT (gstring));
- if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_LBEARING)))
- CHECK_FIXNUM (LGSTRING_SLOT (gstring, LGSTRING_IX_LBEARING));
- if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_RBEARING)))
- CHECK_FIXNUM (LGSTRING_SLOT (gstring, LGSTRING_IX_RBEARING));
- if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_WIDTH)))
- CHECK_FIXNAT (LGSTRING_SLOT (gstring, LGSTRING_IX_WIDTH));
- if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT)))
- CHECK_FIXNUM (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT));
- if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT)))
- CHECK_FIXNUM (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT));
-
- for (i = 0; i < LGSTRING_GLYPH_LEN (gstring); i++)
- {
- val = LGSTRING_GLYPH (gstring, i);
- CHECK_VECTOR (val);
- if (ASIZE (val) < LGSTRING_GLYPH_SIZE)
- goto err;
- if (NILP (AREF (val, LGLYPH_IX_CHAR)))
- break;
- CHECK_FIXNAT (AREF (val, LGLYPH_IX_FROM));
- CHECK_FIXNAT (AREF (val, LGLYPH_IX_TO));
- CHECK_CHARACTER (AREF (val, LGLYPH_IX_CHAR));
- if (!NILP (AREF (val, LGLYPH_IX_CODE)))
- CHECK_FIXNAT (AREF (val, LGLYPH_IX_CODE));
- if (!NILP (AREF (val, LGLYPH_IX_WIDTH)))
- CHECK_FIXNAT (AREF (val, LGLYPH_IX_WIDTH));
- if (!NILP (AREF (val, LGLYPH_IX_ADJUSTMENT)))
- {
- val = AREF (val, LGLYPH_IX_ADJUSTMENT);
- CHECK_VECTOR (val);
- if (ASIZE (val) < 3)
- goto err;
- for (j = 0; j < 3; j++)
- CHECK_FIXNUM (AREF (val, j));
- }
- }
- return i;
- err:
- error ("Invalid glyph-string format");
- return -1;
-}
-
-static void
-check_otf_features (Lisp_Object otf_features)
-{
- Lisp_Object val;
-
- CHECK_CONS (otf_features);
- CHECK_SYMBOL (XCAR (otf_features));
- otf_features = XCDR (otf_features);
- CHECK_CONS (otf_features);
- CHECK_SYMBOL (XCAR (otf_features));
- otf_features = XCDR (otf_features);
- for (val = Fcar (otf_features); CONSP (val); val = XCDR (val))
- {
- CHECK_SYMBOL (XCAR (val));
- if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4)
- error ("Invalid OTF GSUB feature: %s",
- SDATA (SYMBOL_NAME (XCAR (val))));
- }
- otf_features = XCDR (otf_features);
- for (val = Fcar (otf_features); CONSP (val); val = XCDR (val))
- {
- CHECK_SYMBOL (XCAR (val));
- if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4)
- error ("Invalid OTF GPOS feature: %s",
- SDATA (SYMBOL_NAME (XCAR (val))));
- }
-}
-
-#ifdef HAVE_LIBOTF
-#include <otf.h>
-
-Lisp_Object otf_list;
-
-static Lisp_Object
-otf_tag_symbol (OTF_Tag tag)
-{
- char name[5];
-
- OTF_tag_name (tag, name);
- return Fintern (make_unibyte_string (name, 4), Qnil);
-}
-
-static OTF *
-otf_open (Lisp_Object file)
-{
- Lisp_Object val = Fassoc (file, otf_list, Qnil);
- OTF *otf;
-
- if (! NILP (val))
- otf = xmint_pointer (XCDR (val));
- else
- {
- otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL;
- val = make_mint_ptr (otf);
- otf_list = Fcons (Fcons (file, val), otf_list);
- }
- return otf;
-}
-
-
-/* Return a list describing which scripts/languages FONT supports by
- which GSUB/GPOS features of OpenType tables. See the comment of
- (struct font_driver).otf_capability. */
-
-Lisp_Object
-font_otf_capability (struct font *font)
-{
- OTF *otf;
- Lisp_Object capability = Fcons (Qnil, Qnil);
- int i;
-
- otf = otf_open (font->props[FONT_FILE_INDEX]);
- if (! otf)
- return Qnil;
- for (i = 0; i < 2; i++)
- {
- OTF_GSUB_GPOS *gsub_gpos;
- Lisp_Object script_list = Qnil;
- int j;
-
- if (OTF_get_features (otf, i == 0) < 0)
- continue;
- gsub_gpos = i == 0 ? otf->gsub : otf->gpos;
- for (j = gsub_gpos->ScriptList.ScriptCount - 1; j >= 0; j--)
- {
- OTF_Script *script = gsub_gpos->ScriptList.Script + j;
- Lisp_Object langsys_list = Qnil;
- Lisp_Object script_tag = otf_tag_symbol (script->ScriptTag);
- int k;
-
- for (k = script->LangSysCount; k >= 0; k--)
- {
- OTF_LangSys *langsys;
- Lisp_Object feature_list = Qnil;
- Lisp_Object langsys_tag;
- int l;
-
- if (k == script->LangSysCount)
- {
- langsys = &script->DefaultLangSys;
- langsys_tag = Qnil;
- }
- else
- {
- langsys = script->LangSys + k;
- langsys_tag
- = otf_tag_symbol (script->LangSysRecord[k].LangSysTag);
- }
- for (l = langsys->FeatureCount - 1; l >= 0; l--)
- {
- OTF_Feature *feature
- = gsub_gpos->FeatureList.Feature + langsys->FeatureIndex[l];
- Lisp_Object feature_tag
- = otf_tag_symbol (feature->FeatureTag);
-
- feature_list = Fcons (feature_tag, feature_list);
- }
- langsys_list = Fcons (Fcons (langsys_tag, feature_list),
- langsys_list);
- }
- script_list = Fcons (Fcons (script_tag, langsys_list),
- script_list);
- }
-
- if (i == 0)
- XSETCAR (capability, script_list);
- else
- XSETCDR (capability, script_list);
- }
-
- return capability;
-}
-
-/* Parse OTF features in SPEC and write a proper features spec string
- in FEATURES for the call of OTF_drive_gsub/gpos (of libotf). It is
- assured that the sufficient memory has already allocated for
- FEATURES. */
-
-static void
-generate_otf_features (Lisp_Object spec, char *features)
-{
- Lisp_Object val;
- char *p;
- bool asterisk;
-
- p = features;
- *p = '\0';
- for (asterisk = 0; CONSP (spec); spec = XCDR (spec))
- {
- val = XCAR (spec);
- CHECK_SYMBOL (val);
- if (p > features)
- *p++ = ',';
- if (SREF (SYMBOL_NAME (val), 0) == '*')
- {
- asterisk = 1;
- *p++ = '*';
- }
- else if (! asterisk)
- {
- val = SYMBOL_NAME (val);
- p += esprintf (p, "%s", SDATA (val));
- }
- else
- {
- val = SYMBOL_NAME (val);
- p += esprintf (p, "~%s", SDATA (val));
- }
- }
- if (CONSP (spec))
- error ("OTF spec too long");
-}
-
-Lisp_Object
-font_otf_DeviceTable (OTF_DeviceTable *device_table)
-{
- int len = device_table->StartSize - device_table->EndSize + 1;
-
- return Fcons (make_fixnum (len),
- make_unibyte_string (device_table->DeltaValue, len));
-}
-
-Lisp_Object
-font_otf_ValueRecord (int value_format, OTF_ValueRecord *value_record)
-{
- Lisp_Object val = make_nil_vector (8);
-
- if (value_format & OTF_XPlacement)
- ASET (val, 0, make_fixnum (value_record->XPlacement));
- if (value_format & OTF_YPlacement)
- ASET (val, 1, make_fixnum (value_record->YPlacement));
- if (value_format & OTF_XAdvance)
- ASET (val, 2, make_fixnum (value_record->XAdvance));
- if (value_format & OTF_YAdvance)
- ASET (val, 3, make_fixnum (value_record->YAdvance));
- if (value_format & OTF_XPlaDevice)
- ASET (val, 4, font_otf_DeviceTable (&value_record->XPlaDevice));
- if (value_format & OTF_YPlaDevice)
- ASET (val, 4, font_otf_DeviceTable (&value_record->YPlaDevice));
- if (value_format & OTF_XAdvDevice)
- ASET (val, 4, font_otf_DeviceTable (&value_record->XAdvDevice));
- if (value_format & OTF_YAdvDevice)
- ASET (val, 4, font_otf_DeviceTable (&value_record->YAdvDevice));
- return val;
-}
-
-Lisp_Object
-font_otf_Anchor (OTF_Anchor *anchor)
-{
- Lisp_Object val = make_nil_vector (anchor->AnchorFormat + 1);
- ASET (val, 0, make_fixnum (anchor->XCoordinate));
- ASET (val, 1, make_fixnum (anchor->YCoordinate));
- if (anchor->AnchorFormat == 2)
- ASET (val, 2, make_fixnum (anchor->f.f1.AnchorPoint));
- else
- {
- ASET (val, 3, font_otf_DeviceTable (&anchor->f.f2.XDeviceTable));
- ASET (val, 4, font_otf_DeviceTable (&anchor->f.f2.YDeviceTable));
- }
- return val;
-}
-#endif /* HAVE_LIBOTF */
-#endif /* 0 */
-
-
/* Font sorting. */
static double
@@ -4041,7 +3751,7 @@ which kind of font it is. It must be one of `font-spec', `font-entity',
return (FONT_ENTITY_P (object) ? Qt : Qnil);
if (EQ (extra_type, Qfont_object))
return (FONT_OBJECT_P (object) ? Qt : Qnil);
- wrong_type_argument (intern ("font-extra-type"), extra_type);
+ wrong_type_argument (Qfont_extra_type, extra_type); ;
}
DEFUN ("font-spec", Ffont_spec, Sfont_spec, 0, MANY, 0,
@@ -4678,6 +4388,7 @@ GSTRING. */)
from = LGLYPH_FROM (glyph);
to = LGLYPH_TO (glyph);
}
+ composition_gstring_adjust_zero_width (gstring);
return composition_gstring_put_cache (gstring, XFIXNUM (n));
shaper_error:
@@ -4728,7 +4439,8 @@ where
that apply to POSITION. POSITION may be nil, in which case,
FONT-SPEC is the font for displaying the character CH with the
default face. GLYPH-CODE is the glyph code in the font to use for
- the character, as an integer.
+ the character, it is a fixnum, if it is small enough, otherwise a
+ bignum.
For a text terminal, return a nonnegative integer glyph code for
the character, or a negative integer if the character is not
@@ -4818,8 +4530,300 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
return Fcons (font_object, INT_TO_INTEGER (code));
}
+
+/* This part (through the next ^L) is still experimental and not
+ tested much. We may drastically change codes. */
+
+/* This code implements support for extracting OTF features of a font
+ and exposing them to Lisp, including application of those features
+ to arbitrary stretches of text. FIXME: it would be good to finish
+ this work and have this in Emacs. */
+
+/* OTF handler. */
+
#if 0
+#define LGSTRING_HEADER_SIZE 6
+#define LGSTRING_GLYPH_SIZE 8
+
+static int
+check_gstring (Lisp_Object gstring)
+{
+ Lisp_Object val;
+ ptrdiff_t i;
+ int j;
+
+ CHECK_VECTOR (gstring);
+ val = AREF (gstring, 0);
+ CHECK_VECTOR (val);
+ if (ASIZE (val) < LGSTRING_HEADER_SIZE)
+ goto err;
+ CHECK_FONT_OBJECT (LGSTRING_FONT (gstring));
+ if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_LBEARING)))
+ CHECK_FIXNUM (LGSTRING_SLOT (gstring, LGSTRING_IX_LBEARING));
+ if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_RBEARING)))
+ CHECK_FIXNUM (LGSTRING_SLOT (gstring, LGSTRING_IX_RBEARING));
+ if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_WIDTH)))
+ CHECK_FIXNAT (LGSTRING_SLOT (gstring, LGSTRING_IX_WIDTH));
+ if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT)))
+ CHECK_FIXNUM (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT));
+ if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT)))
+ CHECK_FIXNUM (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT));
+
+ for (i = 0; i < LGSTRING_GLYPH_LEN (gstring); i++)
+ {
+ val = LGSTRING_GLYPH (gstring, i);
+ CHECK_VECTOR (val);
+ if (ASIZE (val) < LGSTRING_GLYPH_SIZE)
+ goto err;
+ if (NILP (AREF (val, LGLYPH_IX_CHAR)))
+ break;
+ CHECK_FIXNAT (AREF (val, LGLYPH_IX_FROM));
+ CHECK_FIXNAT (AREF (val, LGLYPH_IX_TO));
+ CHECK_CHARACTER (AREF (val, LGLYPH_IX_CHAR));
+ if (!NILP (AREF (val, LGLYPH_IX_CODE)))
+ CHECK_FIXNAT (AREF (val, LGLYPH_IX_CODE));
+ if (!NILP (AREF (val, LGLYPH_IX_WIDTH)))
+ CHECK_FIXNAT (AREF (val, LGLYPH_IX_WIDTH));
+ if (!NILP (AREF (val, LGLYPH_IX_ADJUSTMENT)))
+ {
+ val = AREF (val, LGLYPH_IX_ADJUSTMENT);
+ CHECK_VECTOR (val);
+ if (ASIZE (val) < 3)
+ goto err;
+ for (j = 0; j < 3; j++)
+ CHECK_FIXNUM (AREF (val, j));
+ }
+ }
+ return i;
+ err:
+ error ("Invalid glyph-string format");
+ return -1;
+}
+
+static void
+check_otf_features (Lisp_Object otf_features)
+{
+ Lisp_Object val;
+
+ CHECK_CONS (otf_features);
+ CHECK_SYMBOL (XCAR (otf_features));
+ otf_features = XCDR (otf_features);
+ CHECK_CONS (otf_features);
+ CHECK_SYMBOL (XCAR (otf_features));
+ otf_features = XCDR (otf_features);
+ for (val = Fcar (otf_features); CONSP (val); val = XCDR (val))
+ {
+ CHECK_SYMBOL (XCAR (val));
+ if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4)
+ error ("Invalid OTF GSUB feature: %s",
+ SDATA (SYMBOL_NAME (XCAR (val))));
+ }
+ otf_features = XCDR (otf_features);
+ for (val = Fcar (otf_features); CONSP (val); val = XCDR (val))
+ {
+ CHECK_SYMBOL (XCAR (val));
+ if (SBYTES (SYMBOL_NAME (XCAR (val))) > 4)
+ error ("Invalid OTF GPOS feature: %s",
+ SDATA (SYMBOL_NAME (XCAR (val))));
+ }
+}
+
+#ifdef HAVE_LIBOTF
+#include <otf.h>
+
+Lisp_Object otf_list;
+
+static Lisp_Object
+otf_tag_symbol (OTF_Tag tag)
+{
+ char name[5];
+
+ OTF_tag_name (tag, name);
+ return Fintern (make_unibyte_string (name, 4), Qnil);
+}
+
+static OTF *
+otf_open (Lisp_Object file)
+{
+ Lisp_Object val = Fassoc (file, otf_list, Qnil);
+ OTF *otf;
+
+ if (! NILP (val))
+ otf = xmint_pointer (XCDR (val));
+ else
+ {
+ otf = STRINGP (file) ? OTF_open (SSDATA (file)) : NULL;
+ val = make_mint_ptr (otf);
+ otf_list = Fcons (Fcons (file, val), otf_list);
+ }
+ return otf;
+}
+
+
+/* Return a list describing which scripts/languages FONT supports by
+ which GSUB/GPOS features of OpenType tables. See the comment of
+ (struct font_driver).otf_capability. */
+
+Lisp_Object
+font_otf_capability (struct font *font)
+{
+ OTF *otf;
+ Lisp_Object capability = Fcons (Qnil, Qnil);
+ int i;
+
+ otf = otf_open (font->props[FONT_FILE_INDEX]);
+ if (! otf)
+ return Qnil;
+ for (i = 0; i < 2; i++)
+ {
+ OTF_GSUB_GPOS *gsub_gpos;
+ Lisp_Object script_list = Qnil;
+ int j;
+
+ if (OTF_get_features (otf, i == 0) < 0)
+ continue;
+ gsub_gpos = i == 0 ? otf->gsub : otf->gpos;
+ for (j = gsub_gpos->ScriptList.ScriptCount - 1; j >= 0; j--)
+ {
+ OTF_Script *script = gsub_gpos->ScriptList.Script + j;
+ Lisp_Object langsys_list = Qnil;
+ Lisp_Object script_tag = otf_tag_symbol (script->ScriptTag);
+ int k;
+
+ for (k = script->LangSysCount; k >= 0; k--)
+ {
+ OTF_LangSys *langsys;
+ Lisp_Object feature_list = Qnil;
+ Lisp_Object langsys_tag;
+ int l;
+
+ if (k == script->LangSysCount)
+ {
+ langsys = &script->DefaultLangSys;
+ langsys_tag = Qnil;
+ }
+ else
+ {
+ langsys = script->LangSys + k;
+ langsys_tag
+ = otf_tag_symbol (script->LangSysRecord[k].LangSysTag);
+ }
+ for (l = langsys->FeatureCount - 1; l >= 0; l--)
+ {
+ OTF_Feature *feature
+ = gsub_gpos->FeatureList.Feature + langsys->FeatureIndex[l];
+ Lisp_Object feature_tag
+ = otf_tag_symbol (feature->FeatureTag);
+
+ feature_list = Fcons (feature_tag, feature_list);
+ }
+ langsys_list = Fcons (Fcons (langsys_tag, feature_list),
+ langsys_list);
+ }
+ script_list = Fcons (Fcons (script_tag, langsys_list),
+ script_list);
+ }
+
+ if (i == 0)
+ XSETCAR (capability, script_list);
+ else
+ XSETCDR (capability, script_list);
+ }
+
+ return capability;
+}
+
+/* Parse OTF features in SPEC and write a proper features spec string
+ in FEATURES for the call of OTF_drive_gsub/gpos (of libotf). It is
+ assured that the sufficient memory has already allocated for
+ FEATURES. */
+
+static void
+generate_otf_features (Lisp_Object spec, char *features)
+{
+ Lisp_Object val;
+ char *p;
+ bool asterisk;
+
+ p = features;
+ *p = '\0';
+ for (asterisk = 0; CONSP (spec); spec = XCDR (spec))
+ {
+ val = XCAR (spec);
+ CHECK_SYMBOL (val);
+ if (p > features)
+ *p++ = ',';
+ if (SREF (SYMBOL_NAME (val), 0) == '*')
+ {
+ asterisk = 1;
+ *p++ = '*';
+ }
+ else if (! asterisk)
+ {
+ val = SYMBOL_NAME (val);
+ p += esprintf (p, "%s", SDATA (val));
+ }
+ else
+ {
+ val = SYMBOL_NAME (val);
+ p += esprintf (p, "~%s", SDATA (val));
+ }
+ }
+ if (CONSP (spec))
+ error ("OTF spec too long");
+}
+
+Lisp_Object
+font_otf_DeviceTable (OTF_DeviceTable *device_table)
+{
+ int len = device_table->StartSize - device_table->EndSize + 1;
+
+ return Fcons (make_fixnum (len),
+ make_unibyte_string (device_table->DeltaValue, len));
+}
+
+Lisp_Object
+font_otf_ValueRecord (int value_format, OTF_ValueRecord *value_record)
+{
+ Lisp_Object val = make_nil_vector (8);
+
+ if (value_format & OTF_XPlacement)
+ ASET (val, 0, make_fixnum (value_record->XPlacement));
+ if (value_format & OTF_YPlacement)
+ ASET (val, 1, make_fixnum (value_record->YPlacement));
+ if (value_format & OTF_XAdvance)
+ ASET (val, 2, make_fixnum (value_record->XAdvance));
+ if (value_format & OTF_YAdvance)
+ ASET (val, 3, make_fixnum (value_record->YAdvance));
+ if (value_format & OTF_XPlaDevice)
+ ASET (val, 4, font_otf_DeviceTable (&value_record->XPlaDevice));
+ if (value_format & OTF_YPlaDevice)
+ ASET (val, 4, font_otf_DeviceTable (&value_record->YPlaDevice));
+ if (value_format & OTF_XAdvDevice)
+ ASET (val, 4, font_otf_DeviceTable (&value_record->XAdvDevice));
+ if (value_format & OTF_YAdvDevice)
+ ASET (val, 4, font_otf_DeviceTable (&value_record->YAdvDevice));
+ return val;
+}
+
+Lisp_Object
+font_otf_Anchor (OTF_Anchor *anchor)
+{
+ Lisp_Object val = make_nil_vector (anchor->AnchorFormat + 1);
+ ASET (val, 0, make_fixnum (anchor->XCoordinate));
+ ASET (val, 1, make_fixnum (anchor->YCoordinate));
+ if (anchor->AnchorFormat == 2)
+ ASET (val, 2, make_fixnum (anchor->f.f1.AnchorPoint));
+ else
+ {
+ ASET (val, 3, font_otf_DeviceTable (&anchor->f.f2.XDeviceTable));
+ ASET (val, 4, font_otf_DeviceTable (&anchor->f.f2.YDeviceTable));
+ }
+ return val;
+}
+#endif /* HAVE_LIBOTF */
+
DEFUN ("font-drive-otf", Ffont_drive_otf, Sfont_drive_otf, 6, 6, 0,
doc: /* Apply OpenType features on glyph-string GSTRING-IN.
OTF-FEATURES specifies which features to apply in this format:
@@ -4938,6 +4942,7 @@ corresponding character. */)
}
#endif /* 0 */
+
#ifdef FONT_DEBUG
DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
@@ -5555,6 +5560,10 @@ syms_of_font (void)
DEFSYM (Qopentype, "opentype");
+ /* Currently used by hbfont.c, which has no syms_of_hbfont function
+ of its own. */
+ DEFSYM (Qcanonical_combining_class, "canonical-combining-class");
+
/* Important character set symbols. */
DEFSYM (Qascii_0, "ascii-0");
DEFSYM (Qiso8859_1, "iso8859-1");
@@ -5594,6 +5603,7 @@ syms_of_font (void)
DEFSYM (QL2R, "L2R");
DEFSYM (QR2L, "R2L");
+ DEFSYM (Qfont_extra_type, "font-extra-type");
DEFSYM (Qfont_driver_superseded_by, "font-driver-superseded-by");
scratch_font_spec = Ffont_spec (0, NULL);
diff --git a/src/font.h b/src/font.h
index 06bd297ccb2..3475189206f 100644
--- a/src/font.h
+++ b/src/font.h
@@ -660,7 +660,7 @@ struct font_driver
/* Optional.
Draw glyphs between FROM and TO of S->char2b at (X Y) pixel
- position of frame F with S->FACE and S->GC. If WITH_BACKGROUND,
+ position of frame S->f with S->face and S->gc. If WITH_BACKGROUND,
fill the background in advance. It is assured that WITH_BACKGROUND
is false when (FROM > 0 || TO < S->nchars). */
int (*draw) (struct glyph_string *s, int from, int to,
diff --git a/src/fontset.c b/src/fontset.c
index 1793715450e..4b91eff2ef6 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -922,8 +922,6 @@ face_for_char (struct frame *f, struct face *face, int c,
int face_id;
int id;
- eassert (fontset_id_valid_p (face->fontset));
-
if (ASCII_CHAR_P (c) || CHAR_BYTE8_P (c))
return face->ascii_face->id;
@@ -969,6 +967,7 @@ face_for_char (struct frame *f, struct face *face, int c,
#endif
}
+ eassert (fontset_id_valid_p (face->fontset));
fontset = FONTSET_FROM_ID (face->fontset);
eassert (!BASE_FONTSET_P (fontset));
diff --git a/src/frame.c b/src/frame.c
index 25d71e0769f..f076a5ba54e 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1503,17 +1503,7 @@ do_switch_frame (Lisp_Object frame, int for_deletion, Lisp_Object norecord)
sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window));
- selected_frame = frame;
-
- move_minibuffers_onto_frame (sf, for_deletion);
-
- if (f->select_mini_window_flag
- && !NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt)))
- f->selected_window = f->minibuffer_window;
- f->select_mini_window_flag = false;
-
- if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
- last_nonminibuf_frame = XFRAME (selected_frame);
+ move_minibuffers_onto_frame (sf, frame, for_deletion);
/* If the selected window in the target frame is its mini-window, we move
to a different window, the most recently used one, unless there is a
@@ -1528,6 +1518,20 @@ do_switch_frame (Lisp_Object frame, int for_deletion, Lisp_Object norecord)
Fset_frame_selected_window (frame, w, Qnil);
}
+ /* After setting `selected_frame`, we're temporarily in an inconsistent
+ state where (selected-window) != (frame-selected-window). Until this
+ invariant is restored we should be very careful not to run ELisp code.
+ (bug#58343) */
+ selected_frame = frame;
+
+ if (f->select_mini_window_flag
+ && !NILP (Fminibufferp (XWINDOW (f->minibuffer_window)->contents, Qt)))
+ f->selected_window = f->minibuffer_window;
+ f->select_mini_window_flag = false;
+
+ if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
+ last_nonminibuf_frame = XFRAME (selected_frame);
+
Fselect_window (f->selected_window, norecord);
/* We want to make sure that the next event generates a frame-switch
@@ -2110,7 +2114,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
else
/* Ensure any minibuffers on FRAME are moved onto the selected
frame. */
- move_minibuffers_onto_frame (f, true);
+ move_minibuffers_onto_frame (f, selected_frame, true);
/* Don't let echo_area_window to remain on a deleted frame. */
if (EQ (f->minibuffer_window, echo_area_window))
@@ -6243,7 +6247,7 @@ You can also use a floating number between 0.0 and 1.0. */);
#endif
DEFVAR_LISP ("default-frame-alist", Vdefault_frame_alist,
- doc: /* Alist of default values for frame creation.
+ doc: /* Alist of default values of frame parameters for frame creation.
These may be set in your init file, like this:
(setq default-frame-alist \\='((width . 80) (height . 55) (menu-bar-lines . 1)))
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index e089f9dea85..dc765e5aee4 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -233,6 +233,7 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
cairo_glyph_t stack_glyph;
font->min_width = font->max_width = 0;
font->average_width = font->space_width = 0;
+ int n = 0;
for (char c = 32; c < 127; c++)
{
cairo_glyph_t *glyphs = &stack_glyph;
@@ -252,17 +253,20 @@ ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
stack_glyph.index = 0;
}
int this_width = ftcrfont_glyph_extents (font, stack_glyph.index, NULL);
- if (this_width > 0
- && (! font->min_width
- || font->min_width > this_width))
- font->min_width = this_width;
- if (this_width > font->max_width)
- font->max_width = this_width;
- if (c == 32)
- font->space_width = this_width;
- font->average_width += this_width;
+ if (this_width > 0)
+ {
+ if (! font->min_width || font->min_width > this_width)
+ font->min_width = this_width;
+ if (this_width > font->max_width)
+ font->max_width = this_width;
+ if (c == 32)
+ font->space_width = this_width;
+ font->average_width += this_width;
+ n++;
+ }
}
- font->average_width /= 95;
+ if (n)
+ font->average_width /= n;
cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
font->ascent = lround (extents.ascent);
@@ -679,8 +683,12 @@ ftcrhbfont_begin_hb_font (struct font *font, double *position_unit)
hb_font_t *hb_font = fthbfont_begin_hb_font (font, position_unit);
/* HarfBuzz 5 correctly scales bitmap-only fonts without position
unit adjustment.
- (https://github.com/harfbuzz/harfbuzz/issues/489) */
- if (!hb_version_atleast (5, 0, 0)
+ (https://github.com/harfbuzz/harfbuzz/issues/489)
+
+ Update: HarfBuzz 5.2.0 no longer does this for an hb_font_t font
+ object created from a given FT_Face.
+ (https://github.com/harfbuzz/harfbuzz/issues/3788) */
+ if ((hb_version_atleast (5, 2, 0) || !hb_version_atleast (5, 0, 0))
&& ftcrfont_info->bitmap_position_unit)
*position_unit = ftcrfont_info->bitmap_position_unit;
diff --git a/src/haiku_font_support.cc b/src/haiku_font_support.cc
index d824cc59ae2..9a2492c9a13 100644
--- a/src/haiku_font_support.cc
+++ b/src/haiku_font_support.cc
@@ -21,6 +21,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <Font.h>
#include <Rect.h>
#include <AffineTransform.h>
+#include <FindDirectory.h>
+#include <Path.h>
+#include <File.h>
+#include <Message.h>
+#include <OS.h>
+#include <Locker.h>
+#include <NodeMonitor.h>
+#include <Looper.h>
#include <cstring>
#include <cmath>
@@ -39,15 +47,57 @@ struct font_object_cache_bucket
static struct font_object_cache_bucket *font_object_cache[2048];
+/* The current global monospace family and style. */
+static char *fixed_family, *fixed_style;
+
+/* The current global variable-width family and style. */
+static char *default_family, *default_style;
+
+/* The sizes of each of those fonts. */
+static float default_size, fixed_size;
+
+/* The locker controlling access to those variables. */
+static BLocker default_locker;
+
/* Haiku doesn't expose font language data in BFont objects. Thus, we
select a few representative characters for each supported `:lang'
(currently Chinese, Korean and Japanese,) and test for those
instead. */
static int language_code_points[MAX_LANGUAGE][3] =
- {{20154, 20754, 22996}, /* Chinese. */
- {51312, 49440, 44544}, /* Korean. */
- {26085, 26412, 12371}, /* Japanese. */};
+ {
+ {20154, 20754, 22996}, /* Chinese. */
+ {51312, 49440, 44544}, /* Korean. */
+ {26085, 26412, 12371}, /* Japanese. */
+ };
+
+static void be_send_font_settings (void);
+
+/* Looper used to track changes to system-wide font settings. */
+class EmacsFontMonitorLooper : public BLooper
+{
+ void
+ MessageReceived (BMessage *msg)
+ {
+ int32 opcode;
+
+ if (msg->what != B_NODE_MONITOR)
+ return;
+
+ if (msg->FindInt32 ("opcode", &opcode) != B_OK)
+ return;
+
+ if (opcode != B_STAT_CHANGED)
+ return;
+
+ /* Wait a little for any message to be completely written after
+ the file's modification time changes. */
+ snooze (10000);
+
+ /* Read and apply font settings. */
+ be_send_font_settings ();
+ }
+};
static unsigned int
hash_string (const char *name_or_style)
@@ -288,12 +338,15 @@ BFont_nchar_bounds (void *font, const char *mb_str, int *advance,
}
static void
-font_style_to_flags (char *st, struct haiku_font_pattern *pattern)
+font_style_to_flags (const char *style_string,
+ struct haiku_font_pattern *pattern)
{
- char *style = strdup (st);
+ char *style;
char *token;
int tok = 0;
+ style = strdup (style_string);
+
if (!style)
return;
@@ -385,7 +438,8 @@ font_style_to_flags (char *st, struct haiku_font_pattern *pattern)
pattern->specified &= ~FSPEC_WEIGHT;
pattern->specified &= ~FSPEC_WIDTH;
pattern->specified |= FSPEC_STYLE;
- std::strncpy ((char *) &pattern->style, st,
+ std::strncpy ((char *) &pattern->style,
+ style_string,
sizeof pattern->style - 1);
pattern->style[sizeof pattern->style - 1] = '\0';
}
@@ -887,7 +941,7 @@ be_evict_font_cache (void)
}
void
-be_font_style_to_flags (char *style, struct haiku_font_pattern *pattern)
+be_font_style_to_flags (const char *style, struct haiku_font_pattern *pattern)
{
pattern->specified = 0;
@@ -939,3 +993,217 @@ be_set_font_antialiasing (void *font, bool antialias_p)
? B_FORCE_ANTIALIASING
: B_DISABLE_ANTIALIASING);
}
+
+static void
+be_send_font_settings (void)
+{
+ struct haiku_font_change_event rq;
+ BFile file;
+ BPath path;
+ status_t rc;
+ BMessage message;
+ font_family family;
+ font_style style;
+ const char *new_family, *new_style;
+ float new_size;
+
+ rc = find_directory (B_USER_SETTINGS_DIRECTORY, &path);
+
+ if (rc < B_OK)
+ return;
+
+ rc = path.Append ("system/app_server/fonts");
+
+ if (rc < B_OK)
+ return;
+
+ if (file.SetTo (path.Path (), B_READ_ONLY) != B_OK)
+ return;
+
+ if (message.Unflatten (&file) != B_OK)
+ return;
+
+ /* Now, populate with new values. */
+ if (!default_locker.Lock ())
+ gui_abort ("Failed to lock font data locker");
+
+ /* Obtain default values. */
+ be_fixed_font->GetFamilyAndStyle (&family, &style);
+ default_size = be_fixed_font->Size ();
+
+ /* And the new values. */
+ new_family = message.GetString ("fixed family", family);
+ new_style = message.GetString ("fixed style", style);
+ new_size = message.GetFloat ("fixed size", default_size);
+
+ /* If it turns out the fixed family changed, send the new family and
+ style. */
+
+ if (!fixed_family || !fixed_style
+ || new_size != fixed_size
+ || strcmp (new_family, fixed_family)
+ || strcmp (new_style, fixed_style))
+ {
+ memset (&rq, 0, sizeof rq);
+ strncpy (rq.new_family, (char *) new_family,
+ sizeof rq.new_family - 1);
+ strncpy (rq.new_style, (char *) new_style,
+ sizeof rq.new_style - 1);
+ rq.new_size = new_size;
+ rq.what = FIXED_FAMILY;
+
+ haiku_write (FONT_CHANGE_EVENT, &rq);
+ }
+
+ if (fixed_family)
+ free (fixed_family);
+
+ if (fixed_style)
+ free (fixed_style);
+
+ fixed_family = strdup (new_family);
+ fixed_style = strdup (new_style);
+ fixed_size = new_size;
+
+ /* Obtain default values. */
+ be_plain_font->GetFamilyAndStyle (&family, &style);
+ default_size = be_plain_font->Size ();
+
+ /* And the new values. */
+ new_family = message.GetString ("plain family", family);
+ new_style = message.GetString ("plain style", style);
+ new_size = message.GetFloat ("plain style", default_size);
+
+ if (!default_family || !default_style
+ || new_size != default_size
+ || strcmp (new_family, default_family)
+ || strcmp (new_style, default_style))
+ {
+ memset (&rq, 0, sizeof rq);
+ strncpy (rq.new_family, (char *) new_family,
+ sizeof rq.new_family - 1);
+ strncpy (rq.new_style, (char *) new_style,
+ sizeof rq.new_style - 1);
+ rq.new_size = new_size;
+ rq.what = DEFAULT_FAMILY;
+
+ haiku_write (FONT_CHANGE_EVENT, &rq);
+ }
+
+ if (default_family)
+ free (default_family);
+
+ if (default_style)
+ free (default_style);
+
+ default_family = strdup (new_family);
+ default_style = strdup (new_style);
+ default_size = new_size;
+
+ default_locker.Unlock ();
+}
+
+/* Begin listening to font settings changes, by installing a node
+ watcher. This relies on the settings file already being present
+ and has several inherent race conditions, but users shouldn't be
+ changing font settings very quickly. */
+
+void
+be_listen_font_settings (void)
+{
+ BPath path;
+ status_t rc;
+ BNode node;
+ node_ref node_ref;
+ EmacsFontMonitorLooper *looper;
+ font_family family;
+ font_style style;
+
+ /* Set up initial values. */
+ be_fixed_font->GetFamilyAndStyle (&family, &style);
+ fixed_family = strdup (family);
+ fixed_style = strdup (style);
+ fixed_size = be_fixed_font->Size ();
+
+ be_plain_font->GetFamilyAndStyle (&family, &style);
+ default_family = strdup (family);
+ default_style = strdup (style);
+ default_size = be_plain_font->Size ();
+
+ rc = find_directory (B_USER_SETTINGS_DIRECTORY, &path);
+
+ if (rc < B_OK)
+ return;
+
+ rc = path.Append ("system/app_server/fonts");
+
+ if (rc < B_OK)
+ return;
+
+ rc = node.SetTo (path.Path ());
+
+ if (rc < B_OK)
+ return;
+
+ if (node.GetNodeRef (&node_ref) < B_OK)
+ return;
+
+ looper = new EmacsFontMonitorLooper;
+
+ if (watch_node (&node_ref, B_WATCH_STAT, looper) < B_OK)
+ {
+ delete looper;
+ return;
+ }
+
+ looper->Run ();
+}
+
+bool
+be_lock_font_defaults (void)
+{
+ return default_locker.Lock ();
+}
+
+void
+be_unlock_font_defaults (void)
+{
+ return default_locker.Unlock ();
+}
+
+const char *
+be_get_font_default (enum haiku_what_font what)
+{
+ switch (what)
+ {
+ case FIXED_FAMILY:
+ return fixed_family;
+
+ case FIXED_STYLE:
+ return fixed_style;
+
+ case DEFAULT_FAMILY:
+ return default_family;
+
+ case DEFAULT_STYLE:
+ return default_style;
+ }
+
+ return NULL;
+}
+
+int
+be_get_font_size (enum haiku_what_font what)
+{
+ switch (what)
+ {
+ case FIXED_FAMILY:
+ return fixed_size;
+
+ case DEFAULT_FAMILY:
+ return default_size;
+
+ default:
+ return 0;
+ }
+}
diff --git a/src/haiku_io.c b/src/haiku_io.c
index 5cc70f6f71f..6ef6f2ebd06 100644
--- a/src/haiku_io.c
+++ b/src/haiku_io.c
@@ -109,6 +109,8 @@ haiku_len (enum haiku_event_type type)
return sizeof (struct haiku_screen_changed_event);
case CLIPBOARD_CHANGED_EVENT:
return sizeof (struct haiku_clipboard_changed_event);
+ case FONT_CHANGE_EVENT:
+ return sizeof (struct haiku_font_change_event);
}
emacs_abort ();
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 983928442a1..0f8e26d0db4 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -54,12 +54,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <game/WindowScreen.h>
#include <game/DirectWindow.h>
+#include <storage/FindDirectory.h>
#include <storage/Entry.h>
#include <storage/Path.h>
#include <storage/FilePanel.h>
#include <storage/AppFileInfo.h>
#include <storage/Path.h>
#include <storage/PathFinder.h>
+#include <storage/Node.h>
#include <support/Beep.h>
#include <support/DataIO.h>
@@ -5501,3 +5503,54 @@ be_set_use_frame_synchronization (void *view, bool sync)
vw = (EmacsView *) view;
vw->SetFrameSynchronization (sync);
}
+
+status_t
+be_write_node_message (const char *path, const char *name, void *message)
+{
+ BNode node (path);
+ status_t rc;
+ ssize_t flat, result;
+ char *buffer;
+ BMessage *msg;
+
+ rc = node.InitCheck ();
+ msg = (BMessage *) message;
+
+ if (rc < B_OK)
+ return rc;
+
+ flat = msg->FlattenedSize ();
+ if (flat < B_OK)
+ return flat;
+
+ buffer = new (std::nothrow) char[flat];
+ if (!buffer)
+ return B_NO_MEMORY;
+
+ rc = msg->Flatten (buffer, flat);
+ if (rc < B_OK)
+ {
+ delete[] buffer;
+ return rc;
+ }
+
+ result = node.WriteAttr (name, B_MIME_TYPE, 0,
+ buffer, flat);
+ delete[] buffer;
+
+ if (result < B_OK)
+ return result;
+
+ if (result != flat)
+ return B_ERROR;
+
+ return B_OK;
+}
+
+void
+be_send_message (const char *app_id, void *message)
+{
+ BMessenger messenger (app_id);
+
+ messenger.SendMessage ((BMessage *) message);
+}
diff --git a/src/haiku_support.h b/src/haiku_support.h
index ca1808556a4..e940e69bf11 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -115,6 +115,7 @@ enum haiku_event_type
SCREEN_CHANGED_EVENT,
MENU_BAR_LEFT,
CLIPBOARD_CHANGED_EVENT,
+ FONT_CHANGE_EVENT,
};
struct haiku_clipboard_changed_event
@@ -442,6 +443,27 @@ struct haiku_menu_bar_state_event
void *window;
};
+enum haiku_what_font
+ {
+ FIXED_FAMILY,
+ FIXED_STYLE,
+ DEFAULT_FAMILY,
+ DEFAULT_STYLE,
+ };
+
+struct haiku_font_change_event
+{
+ /* New family, style and size of the font. */
+ haiku_font_family_or_style new_family;
+ haiku_font_family_or_style new_style;
+ int new_size;
+
+ /* What changed. FIXED_FAMILY means this is the new fixed font.
+ DEFAULT_FAMILY means this is the new plain font. The other enums
+ have no meaning. */
+ enum haiku_what_font what;
+};
+
struct haiku_session_manager_reply
{
bool quit_reply;
@@ -697,7 +719,7 @@ extern int be_get_display_screens (void);
extern bool be_use_subpixel_antialiasing (void);
extern const char *be_find_setting (const char *);
extern haiku_font_family_or_style *be_list_font_families (size_t *);
-extern void be_font_style_to_flags (char *, struct haiku_font_pattern *);
+extern void be_font_style_to_flags (const char *, struct haiku_font_pattern *);
extern void *be_open_font_at_index (int, int, float);
extern void be_set_font_antialiasing (void *, bool);
extern int be_get_ui_color (const char *, uint32_t *);
@@ -724,11 +746,21 @@ extern void be_get_window_decorator_frame (void *, int *, int *, int *, int *);
extern void be_send_move_frame_event (void *);
extern void be_set_window_fullscreen_mode (void *, enum haiku_fullscreen_mode);
+extern status_t be_write_node_message (const char *, const char *, void *);
+extern void be_send_message (const char *, void *);
+
extern void be_lock_window (void *);
extern void be_unlock_window (void *);
extern bool be_get_explicit_workarea (int *, int *, int *, int *);
extern void be_clear_grab_view (void);
extern void be_set_use_frame_synchronization (void *, bool);
+
+extern void be_listen_font_settings (void);
+
+extern bool be_lock_font_defaults (void);
+extern const char *be_get_font_default (enum haiku_what_font);
+extern int be_get_font_size (enum haiku_what_font);
+extern void be_unlock_font_defaults (void);
#ifdef __cplusplus
}
diff --git a/src/haikufns.c b/src/haikufns.c
index aaa4e866228..711202c5df3 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -2636,8 +2636,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
start_timer:
/* Let the tip disappear after timeout seconds. */
- tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
- intern ("x-hide-tip"));
+ tip_timer = call3 (Qrun_at_time, timeout, Qnil, Qx_hide_tip);
return unbind_to (count, Qnil);
}
@@ -3149,6 +3148,9 @@ syms_of_haikufns (void)
DEFSYM (Qcancel_timer, "cancel-timer");
DEFSYM (Qassq_delete_all, "assq-delete-all");
+ DEFSYM (Qrun_at_time, "run-at-time");
+ DEFSYM (Qx_hide_tip, "x-hide-tip");
+
DEFSYM (Qalways, "always");
DEFSYM (Qnot_useful, "not-useful");
DEFSYM (Qwhen_mapped, "when-mapped");
diff --git a/src/haikufont.c b/src/haikufont.c
index 3e7f6f86dcb..335c312cebe 100644
--- a/src/haikufont.c
+++ b/src/haikufont.c
@@ -370,7 +370,7 @@ haikufont_maybe_handle_special_family (Lisp_Object family,
BFont_populate_fixed_family (ptn);
return 1;
}
- else if (EQ (family, intern ("Sans Serif")))
+ else if (EQ (family, QSans_Serif))
{
BFont_populate_plain_family (ptn);
return 1;
@@ -1311,6 +1311,98 @@ in the font selection dialog. */)
QCsize, lsize);
}
+DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
+ Sfont_get_system_normal_font, 0, 0, 0,
+ doc: /* SKIP: real doc in xsettings.c. */)
+ (void)
+{
+ Lisp_Object value;
+ const char *name, *style;
+ struct haiku_font_pattern pattern;
+ Lisp_Object lfamily, lweight, lslant, lwidth, ladstyle;
+ int size;
+
+ if (!be_lock_font_defaults ())
+ return Qnil;
+
+ name = be_get_font_default (DEFAULT_FAMILY);
+ style = be_get_font_default (DEFAULT_STYLE);
+ size = be_get_font_size (DEFAULT_FAMILY);
+
+ be_font_style_to_flags (style, &pattern);
+
+ lfamily = build_string_from_utf8 (name);
+ lweight = (pattern.specified & FSPEC_WEIGHT
+ ? haikufont_weight_to_lisp (pattern.weight) : Qnil);
+ lslant = (pattern.specified & FSPEC_SLANT
+ ? haikufont_slant_to_lisp (pattern.slant) : Qnil);
+ lwidth = (pattern.specified & FSPEC_WIDTH
+ ? haikufont_width_to_lisp (pattern.width) : Qnil);
+ ladstyle = (pattern.specified & FSPEC_STYLE
+ ? intern (pattern.style) : Qnil);
+
+ value = CALLN (Ffont_spec, QCfamily, lfamily,
+ QCweight, lweight, QCslant, lslant,
+ QCwidth, lwidth, QCadstyle, ladstyle,
+ QCsize, make_fixnum (size));
+ be_unlock_font_defaults ();
+
+ return value;
+}
+
+DEFUN ("font-get-system-font", Ffont_get_system_font,
+ Sfont_get_system_font, 0, 0, 0,
+ doc: /* SKIP: real doc in xsettings.c. */)
+ (void)
+{
+ Lisp_Object value;
+ const char *name, *style;
+ struct haiku_font_pattern pattern;
+ Lisp_Object lfamily, lweight, lslant, lwidth, ladstyle;
+ int size;
+
+ if (!be_lock_font_defaults ())
+ return Qnil;
+
+ name = be_get_font_default (FIXED_FAMILY);
+ style = be_get_font_default (FIXED_STYLE);
+ size = be_get_font_size (FIXED_FAMILY);
+
+ be_font_style_to_flags (style, &pattern);
+
+ lfamily = build_string_from_utf8 (name);
+ lweight = (pattern.specified & FSPEC_WEIGHT
+ ? haikufont_weight_to_lisp (pattern.weight) : Qnil);
+ lslant = (pattern.specified & FSPEC_SLANT
+ ? haikufont_slant_to_lisp (pattern.slant) : Qnil);
+ lwidth = (pattern.specified & FSPEC_WIDTH
+ ? haikufont_width_to_lisp (pattern.width) : Qnil);
+ ladstyle = (pattern.specified & FSPEC_STYLE
+ ? intern (pattern.style) : Qnil);
+
+ value = CALLN (Ffont_spec, QCfamily, lfamily,
+ QCweight, lweight, QCslant, lslant,
+ QCwidth, lwidth, QCadstyle, ladstyle,
+ QCsize, make_fixnum (size));
+ be_unlock_font_defaults ();
+
+ return value;
+}
+
+void
+haiku_handle_font_change_event (struct haiku_font_change_event *event,
+ struct input_event *ie)
+{
+ ie->kind = CONFIG_CHANGED_EVENT;
+
+ /* This is the name of the display. */
+ ie->frame_or_window = XCAR (x_display_list->name_list_element);
+
+ /* And this is the font that changed. */
+ ie->arg = (event->what == FIXED_FAMILY
+ ? Qmonospace_font_name : Qfont_name);
+}
+
static void
syms_of_haikufont_for_pdumper (void)
{
@@ -1320,6 +1412,7 @@ syms_of_haikufont_for_pdumper (void)
void
syms_of_haikufont (void)
{
+ DEFSYM (QSans_Serif, "Sans Serif");
DEFSYM (Qfontsize, "fontsize");
DEFSYM (Qfixed, "fixed");
DEFSYM (Qplain, "plain");
@@ -1343,6 +1436,14 @@ syms_of_haikufont (void)
DEFSYM (QCindices, ":indices");
+ DEFSYM (Qmonospace_font_name, "monospace-font-name");
+ DEFSYM (Qfont_name, "font-name");
+ DEFSYM (Qdynamic_setting, "dynamic-setting");
+
+ DEFVAR_BOOL ("font-use-system-font", use_system_font,
+ doc: /* SKIP: real doc in xsettings.c. */);
+ use_system_font = false;
+
#ifdef USE_BE_CAIRO
Fput (Qhaiku, Qfont_driver_superseded_by, Qftcr);
#endif
@@ -1352,6 +1453,12 @@ syms_of_haikufont (void)
staticpro (&font_cache);
defsubr (&Sx_select_font);
+ defsubr (&Sfont_get_system_normal_font);
+ defsubr (&Sfont_get_system_font);
be_init_font_data ();
+
+ /* This tells loadup to load dynamic-setting.el, which handles
+ config-changed events. */
+ Fprovide (Qdynamic_setting, Qnil);
}
diff --git a/src/haikuselect.c b/src/haikuselect.c
index 7eb93a2754d..bd004f4900a 100644
--- a/src/haikuselect.c
+++ b/src/haikuselect.c
@@ -325,6 +325,15 @@ haiku_message_to_lisp (void *message)
t1 = make_float (*(float *) buf);
break;
+ case 'CSTR':
+ /* Is this even possible? */
+ if (!buf_size)
+ buf_size = 1;
+
+ t1 = make_uninit_string (buf_size - 1);
+ memcpy (SDATA (t1), buf, buf_size - 1);
+ break;
+
default:
t1 = make_uninit_string (buf_size);
memcpy (SDATA (t1), buf, buf_size);
@@ -747,6 +756,21 @@ haiku_lisp_to_message (Lisp_Object obj, void *message)
signal_error ("Failed to add bool", data);
break;
+ case 'CSTR':
+ /* C strings must be handled specially, since they
+ include a trailing NULL byte. */
+ CHECK_STRING (data);
+
+ block_input ();
+ rc = be_add_message_data (message, SSDATA (name),
+ type_code, SDATA (data),
+ SBYTES (data) + 1);
+ unblock_input ();
+
+ if (rc)
+ signal_error ("Failed to add", data);
+ break;
+
default:
decode_normally:
CHECK_STRING (data);
@@ -779,6 +803,49 @@ haiku_unwind_drag_message (void *message)
BMessage_delete (message);
}
+static void
+haiku_report_system_error (status_t code, const char *format)
+{
+ switch (code)
+ {
+ case B_BAD_VALUE:
+ error (format, "Bad value");
+ break;
+
+ case B_ENTRY_NOT_FOUND:
+ error (format, "File not found");
+ break;
+
+ case B_PERMISSION_DENIED:
+ error (format, "Permission denied");
+ break;
+
+ case B_LINK_LIMIT:
+ error (format, "Link limit reached");
+ break;
+
+ case B_BUSY:
+ error (format, "Device busy");
+ break;
+
+ case B_NO_MORE_FDS:
+ error (format, "No more file descriptors");
+ break;
+
+ case B_FILE_ERROR:
+ error (format, "File error");
+ break;
+
+ case B_NO_MEMORY:
+ memory_full (SIZE_MAX);
+ break;
+
+ default:
+ error (format, "Unknown error");
+ break;
+ }
+}
+
DEFUN ("haiku-drag-message", Fhaiku_drag_message, Shaiku_drag_message,
2, 4, 0,
doc: /* Begin dragging MESSAGE from FRAME.
@@ -958,6 +1025,66 @@ after it starts. */)
return SAFE_FREE_UNBIND_TO (depth, Qnil);
}
+DEFUN ("haiku-write-node-attribute", Fhaiku_write_node_attribute,
+ Shaiku_write_node_attribute, 3, 3, 0,
+ doc: /* Write a message as a file-system attribute of NODE.
+FILE should be a file name of a file on a Be File System volume, NAME
+should be a string describing the name of the attribute that will be
+written, and MESSAGE will be the attribute written to FILE, as a
+system message in the format accepted by `haiku-drag-message', which
+see. */)
+ (Lisp_Object file, Lisp_Object name, Lisp_Object message)
+{
+ void *be_message;
+ status_t rc;
+ specpdl_ref count;
+
+ CHECK_STRING (file);
+ CHECK_STRING (name);
+
+ file = ENCODE_FILE (file);
+ name = ENCODE_SYSTEM (name);
+
+ be_message = be_create_simple_message ();
+ count = SPECPDL_INDEX ();
+
+ record_unwind_protect_ptr (BMessage_delete, be_message);
+ haiku_lisp_to_message (message, be_message);
+ rc = be_write_node_message (SSDATA (file), SSDATA (name),
+ be_message);
+
+ if (rc < B_OK)
+ haiku_report_system_error (rc, "Failed to set attribute: %s");
+
+ return unbind_to (count, Qnil);
+}
+
+DEFUN ("haiku-send-message", Fhaiku_send_message, Shaiku_send_message,
+ 2, 2, 0,
+ doc: /* Send a system message to PROGRAM.
+PROGRAM must be the name of the application to which the message will
+be sent. MESSAGE is the system message, serialized in the format
+accepted by `haiku-drag-message', that will be sent to the application
+specified by PROGRAM. There is no guarantee that the message will
+arrive after this function is called. */)
+ (Lisp_Object program, Lisp_Object message)
+{
+ specpdl_ref count;
+ void *be_message;
+
+ CHECK_STRING (program);
+ program = ENCODE_SYSTEM (program);
+
+ be_message = be_create_simple_message ();
+ count = SPECPDL_INDEX ();
+
+ record_unwind_protect_ptr (BMessage_delete, be_message);
+ haiku_lisp_to_message (message, be_message);
+ be_send_message (SSDATA (program), be_message);
+
+ return unbind_to (count, Qnil);
+}
+
static void
haiku_dnd_compute_tip_xy (int *root_x, int *root_y)
{
@@ -1191,6 +1318,8 @@ keyboard modifiers currently held down. */);
defsubr (&Shaiku_selection_owner_p);
defsubr (&Shaiku_drag_message);
defsubr (&Shaiku_roster_launch);
+ defsubr (&Shaiku_write_node_attribute);
+ defsubr (&Shaiku_send_message);
haiku_dnd_frame = NULL;
}
diff --git a/src/haikuterm.c b/src/haikuterm.c
index df1c39974f8..838eb128fa6 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -2988,18 +2988,11 @@ haiku_default_font_parameter (struct frame *f, Lisp_Object parms)
font_param = Qnil;
if (NILP (font_param))
- {
- /* System font should take precedence over X resources. We suggest this
- regardless of font-use-system-font because .emacs may not have been
- read yet. */
- struct haiku_font_pattern ptn;
- ptn.specified = 0;
-
- BFont_populate_fixed_family (&ptn);
-
- if (ptn.specified & FSPEC_FAMILY)
- font = font_open_by_name (f, build_unibyte_string (ptn.family));
- }
+ /* System font should take precedence over X resources. We
+ suggest this regardless of font-use-system-font because .emacs
+ may not have been read yet. Returning a font-spec is Haiku
+ specific behavior. */
+ font = font_open_by_spec (f, Ffont_get_system_font ());
if (NILP (font))
font = !NILP (font_param) ? font_param
@@ -4027,6 +4020,11 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
inev.kind = SAVE_SESSION_EVENT;
inev.arg = Qt;
break;
+ case FONT_CHANGE_EVENT:
+ /* This generates CONFIG_CHANGED_EVENTs, which are then
+ handled in Lisp. */
+ haiku_handle_font_change_event (buf, &inev);
+ break;
case KEY_UP:
case DUMMY_EVENT:
default:
@@ -4349,7 +4347,7 @@ haiku_term_init (void)
emacs_abort ();
color_file = Fexpand_file_name (build_string ("rgb.txt"),
- Fsymbol_value (intern ("data-directory")));
+ Fsymbol_value (Qdata_directory));
color_map = Fx_load_color_file (color_file);
if (NILP (color_map))
@@ -4417,6 +4415,9 @@ haiku_term_init (void)
dpyinfo->default_name = build_string ("GNU Emacs");
haiku_start_watching_selections ();
+
+ /* Start listening for font configuration changes. */
+ be_listen_font_settings ();
unblock_input ();
return dpyinfo;
@@ -4634,6 +4635,8 @@ syms_of_haikuterm (void)
DEFSYM (Qoption, "option");
DEFSYM (Qcommand, "command");
+ DEFSYM (Qdata_directory, "data-directory");
+
DEFVAR_LISP ("haiku-meta-keysym", Vhaiku_meta_keysym,
doc: /* Which key Emacs uses as the meta modifier.
This is either one of the symbols `shift', `control', `command', and
diff --git a/src/haikuterm.h b/src/haikuterm.h
index b603c0a482f..86274fd42a3 100644
--- a/src/haikuterm.h
+++ b/src/haikuterm.h
@@ -34,6 +34,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define HAVE_CHAR_CACHE_MAX 65535
+/* This is really defined in haiku_support.h. */
+struct haiku_font_change_event;
+
extern int popup_activated_p;
struct haikufont_info
@@ -361,4 +364,7 @@ extern void haiku_merge_cursor_foreground (struct glyph_string *, unsigned long
unsigned long *);
extern void haiku_handle_selection_clear (struct input_event *);
extern void haiku_start_watching_selections (void);
+extern void haiku_handle_font_change_event (struct haiku_font_change_event *,
+ struct input_event *);
+
#endif /* _HAIKU_TERM_H_ */
diff --git a/src/hbfont.c b/src/hbfont.c
index 2721a661208..476e08020e1 100644
--- a/src/hbfont.c
+++ b/src/hbfont.c
@@ -249,7 +249,7 @@ uni_combining (hb_unicode_funcs_t *funcs, hb_codepoint_t ch, void *user_data)
if (!combining_class_loaded)
{
canonical_combining_class_table =
- uniprop_table (intern ("canonical-combining-class"));
+ uniprop_table (Qcanonical_combining_class);
if (NILP (canonical_combining_class_table))
emacs_abort ();
staticpro (&canonical_combining_class_table);
diff --git a/src/image.c b/src/image.c
index 549fe30ef7c..1e323ba66a0 100644
--- a/src/image.c
+++ b/src/image.c
@@ -10907,7 +10907,7 @@ DEF_DLL_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *));
DEF_DLL_FN (void, g_type_init, (void));
# endif
DEF_DLL_FN (void, g_object_unref, (gpointer));
-DEF_DLL_FN (void, g_clear_error, (GError **));
+DEF_DLL_FN (void, g_error_free, (GError *));
static bool
init_svg_functions (void)
@@ -10967,7 +10967,7 @@ init_svg_functions (void)
LOAD_DLL_FN (gobject, g_type_init);
# endif
LOAD_DLL_FN (gobject, g_object_unref);
- LOAD_DLL_FN (glib, g_clear_error);
+ LOAD_DLL_FN (glib, g_error_free);
return 1;
}
@@ -10983,7 +10983,7 @@ init_svg_functions (void)
# undef gdk_pixbuf_get_pixels
# undef gdk_pixbuf_get_rowstride
# undef gdk_pixbuf_get_width
-# undef g_clear_error
+# undef g_error_free
# undef g_object_unref
# undef g_type_init
# if LIBRSVG_CHECK_VERSION (2, 52, 1)
@@ -11019,7 +11019,7 @@ init_svg_functions (void)
# define gdk_pixbuf_get_pixels fn_gdk_pixbuf_get_pixels
# define gdk_pixbuf_get_rowstride fn_gdk_pixbuf_get_rowstride
# define gdk_pixbuf_get_width fn_gdk_pixbuf_get_width
-# define g_clear_error fn_g_clear_error
+# define g_error_free fn_g_error_free
# define g_object_unref fn_g_object_unref
# if ! GLIB_CHECK_VERSION (2, 36, 0)
# define g_type_init fn_g_type_init
@@ -11183,6 +11183,10 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
char *wrapped_contents = NULL;
ptrdiff_t wrapped_size;
+ bool empty_errmsg = true;
+ const char *errmsg = "";
+ ptrdiff_t errlen = 0;
+
#if LIBRSVG_CHECK_VERSION (2, 48, 0)
char *css = NULL;
#endif
@@ -11353,7 +11357,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
if (! check_image_size (f, width, height))
{
image_size_error ();
- goto rsvg_error;
+ goto done_error;
}
/* We are now done with the unmodified data. */
@@ -11536,9 +11540,30 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
image_put_x_image (f, img, ximg, 0);
}
+ eassume (err == NULL);
return true;
rsvg_error:
+ if (err && err->message[0])
+ {
+ errmsg = err->message;
+ errlen = strlen (errmsg);
+ /* Remove trailing whitespace from the error message text. It
+ has a newline at the end, and perhaps more whitespace. */
+ while (errlen && c_isspace (errmsg[errlen - 1]))
+ errlen--;
+ empty_errmsg = errlen == 0;
+ }
+
+ if (empty_errmsg)
+ image_error ("Error parsing SVG image");
+ else
+ image_error ("Error parsing SVG image: %s", make_string (errmsg, errlen));
+
+ if (err)
+ g_error_free (err);
+
+ done_error:
if (rsvg_handle)
g_object_unref (rsvg_handle);
if (wrapped_contents)
@@ -11547,10 +11572,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
if (css && !STRINGP (lcss))
xfree (css);
#endif
- image_error ("Error parsing SVG image: %s",
- /* The -1 removes an extra newline. */
- make_string (err->message, strlen (err->message) - 1));
- g_clear_error (&err);
return false;
}
@@ -11817,9 +11838,6 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
/***********************************************************************
Tests
***********************************************************************/
-
-#ifdef GLYPH_DEBUG
-
DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
doc: /* Value is non-nil if SPEC is a valid image specification. */)
(Lisp_Object spec)
@@ -11827,6 +11845,7 @@ DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
return valid_image_p (spec) ? Qt : Qnil;
}
+#ifdef GLYPH_DEBUG
DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0,
doc: /* */)
@@ -12219,9 +12238,9 @@ non-numeric, there is no explicit limit on the size of images. */);
defsubr (&Simage_mask_p);
defsubr (&Simage_metadata);
defsubr (&Simage_cache_size);
+ defsubr (&Simagep);
#ifdef GLYPH_DEBUG
- defsubr (&Simagep);
defsubr (&Slookup_image);
#endif
@@ -12264,5 +12283,4 @@ The options are:
/* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
imagemagick_render_type = 0;
#endif
-
}
diff --git a/src/intervals.c b/src/intervals.c
index 85152c58a5d..7f119815570 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -2171,8 +2171,8 @@ get_property_and_range (ptrdiff_t pos, Lisp_Object prop, Lisp_Object *val,
/* Return the proper local keymap TYPE for position POSITION in
BUFFER; TYPE should be one of `keymap' or `local-map'. Use the map
- specified by the PROP property, if any. Otherwise, if TYPE is
- `local-map' use BUFFER's local map. */
+ specified by the TYPE property, if any. Otherwise, if TYPE is
+ `local-map', use BUFFER's local map. */
Lisp_Object
get_local_map (ptrdiff_t position, struct buffer *buffer, Lisp_Object type)
diff --git a/src/keyboard.c b/src/keyboard.c
index ca51c80da04..8ab4a451b45 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -499,27 +499,18 @@ echo_add_key (Lisp_Object c)
STRING_MULTIBYTE (name), 1);
}
+ Lisp_Object new_string = make_string (buffer, ptr - buffer);
if ((NILP (echo_string) || SCHARS (echo_string) == 0)
&& help_char_p (c))
{
- static const char text[] = " (Type ? for further options)";
- int len = sizeof text - 1;
-
- if (size - (ptr - buffer) < len)
- {
- ptrdiff_t offset = ptr - buffer;
- size += len;
- buffer = SAFE_ALLOCA (size);
- ptr = buffer + offset;
- }
-
- memcpy (ptr, text, len);
- ptr += len;
+ AUTO_STRING (str, " (Type ? for further options)");
+ AUTO_LIST2 (props, Qface, Qhelp_key_binding);
+ Fadd_text_properties (make_fixnum (7), make_fixnum (8), props, str);
+ new_string = concat2 (new_string, str);
}
- kset_echo_string
- (current_kboard,
- concat2 (echo_string, make_string (buffer, ptr - buffer)));
+ kset_echo_string (current_kboard,
+ concat2 (echo_string, new_string));
SAFE_FREE ();
}
@@ -11797,6 +11788,9 @@ DEFUN ("posn-at-point", Fposn_at_point, Sposn_at_point, 0, 2, 0,
doc: /* Return position information for buffer position POS in WINDOW.
POS defaults to point in WINDOW; WINDOW defaults to the selected window.
+If POS is in invisible text or is hidden by `display' properties,
+this function may report on buffer positions before or after POS.
+
Return nil if POS is not visible in WINDOW. Otherwise,
the return value is similar to that returned by `event-start' for
a mouse click at the upper left corner of the glyph corresponding
@@ -12249,6 +12243,8 @@ syms_of_keyboard (void)
DEFSYM (Qhelp_form_show, "help-form-show");
+ DEFSYM (Qhelp_key_binding, "help-key-binding");
+
DEFSYM (Qecho_keystrokes, "echo-keystrokes");
Fset (Qinput_method_exit_on_first_char, Qnil);
diff --git a/src/lisp.h b/src/lisp.h
index 2f73ba4c617..5f6721595c0 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -245,7 +245,8 @@ DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
DEFINE_GDB_SYMBOL_END (VALMASK)
/* Ignore 'alignas' on compilers lacking it. */
-#if !defined alignas && !defined __alignas_is_defined
+#if (!defined alignas && !defined __alignas_is_defined \
+ && __STDC_VERSION__ < 202311 && __cplusplus < 201103)
# define alignas(a)
#endif
@@ -1574,10 +1575,15 @@ struct Lisp_String
{
struct
{
- ptrdiff_t size; /* MSB is used as the markbit. */
- ptrdiff_t size_byte; /* Set to -1 for unibyte strings,
- -2 for data in rodata,
- -3 for immovable unibyte strings. */
+ /* Number of characters in string; MSB is used as the mark bit. */
+ ptrdiff_t size;
+ /* If nonnegative, number of bytes in the string (which is multibyte).
+ If negative, the string is unibyte:
+ -1 for data normally allocated
+ -2 for data in rodata (C string constants)
+ -3 for data that must be immovable (used for bytecode) */
+ ptrdiff_t size_byte;
+
INTERVAL intervals; /* Text properties in this string. */
unsigned char *data;
} s;
@@ -4786,7 +4792,7 @@ extern void clear_regexp_cache (void);
extern Lisp_Object Vminibuffer_list;
extern Lisp_Object last_minibuf_string;
-extern void move_minibuffers_onto_frame (struct frame *, bool);
+extern void move_minibuffers_onto_frame (struct frame *, Lisp_Object, bool);
extern bool is_minibuffer (EMACS_INT, Lisp_Object);
extern EMACS_INT this_minibuffer_depth (Lisp_Object);
extern EMACS_INT minibuf_level;
diff --git a/src/lread.c b/src/lread.c
index d64a4fad3af..dfa4d9afb51 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1423,6 +1423,7 @@ Return t if the file exists and loads successfully. */)
struct stat s1, s2;
int result;
+ struct timespec epoch_timespec = {(time_t)0, 0}; /* 1970-01-01T00:00 UTC */
if (version < 0 && !(version = safe_to_load_version (file, fd)))
error ("File `%s' was not compiled in Emacs", SDATA (found));
@@ -1451,7 +1452,12 @@ Return t if the file exists and loads successfully. */)
newer = 1;
/* If we won't print another message, mention this anyway. */
- if (!NILP (nomessage) && !force_load_messages)
+ if (!NILP (nomessage) && !force_load_messages
+ /* We don't want this message during
+ bootstrapping for the "compile-first" .elc
+ files, which have had their timestamps set to
+ the epoch. See bug #58224. */
+ && timespec_cmp (get_stat_mtime (&s1), epoch_timespec))
{
Lisp_Object msg_file;
msg_file = Fsubstring (found, make_fixnum (0), make_fixnum (-1));
@@ -2914,20 +2920,17 @@ invalid_radix_integer (EMACS_INT radix, Lisp_Object readcharfun)
invalid_syntax (buf, readcharfun);
}
-/* Size of the fixed-size buffer used during reading. */
-enum { stackbufsize = 1024 };
-
/* Read an integer in radix RADIX using READCHARFUN to read
- characters. RADIX must be in the interval [2..36]. Use STACKBUF
- for temporary storage as needed. Value is the integer read.
+ characters. RADIX must be in the interval [2..36].
+ Value is the integer read.
Signal an error if encountering invalid read syntax. */
static Lisp_Object
-read_integer (Lisp_Object readcharfun, int radix,
- char stackbuf[VLA_ELEMS (stackbufsize)])
+read_integer (Lisp_Object readcharfun, int radix)
{
+ char stackbuf[20];
char *read_buffer = stackbuf;
- ptrdiff_t read_buffer_size = stackbufsize;
+ ptrdiff_t read_buffer_size = sizeof stackbuf;
char *p = read_buffer;
char *heapbuf = NULL;
int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */
@@ -3028,11 +3031,11 @@ read_char_literal (Lisp_Object readcharfun)
/* Read a string literal (preceded by '"'). */
static Lisp_Object
-read_string_literal (char stackbuf[VLA_ELEMS (stackbufsize)],
- Lisp_Object readcharfun)
+read_string_literal (Lisp_Object readcharfun)
{
+ char stackbuf[1024];
char *read_buffer = stackbuf;
- ptrdiff_t read_buffer_size = stackbufsize;
+ ptrdiff_t read_buffer_size = sizeof stackbuf;
specpdl_ref count = SPECPDL_INDEX ();
char *heapbuf = NULL;
char *p = read_buffer;
@@ -3355,8 +3358,7 @@ string_props_from_rev_list (Lisp_Object elems, Lisp_Object readcharfun)
/* Read a bool vector (preceded by "#&"). */
static Lisp_Object
-read_bool_vector (char stackbuf[VLA_ELEMS (stackbufsize)],
- Lisp_Object readcharfun)
+read_bool_vector (Lisp_Object readcharfun)
{
ptrdiff_t length = 0;
for (;;)
@@ -3374,7 +3376,7 @@ read_bool_vector (char stackbuf[VLA_ELEMS (stackbufsize)],
}
ptrdiff_t size_in_chars = bool_vector_bytes (length);
- Lisp_Object str = read_string_literal (stackbuf, readcharfun);
+ Lisp_Object str = read_string_literal (readcharfun);
if (STRING_MULTIBYTE (str)
|| !(size_in_chars == SCHARS (str)
/* We used to print 1 char too many when the number of bits
@@ -3696,7 +3698,7 @@ read_stack_reset (intmax_t sp)
static Lisp_Object
read0 (Lisp_Object readcharfun, bool locate_syms)
{
- char stackbuf[stackbufsize];
+ char stackbuf[64];
char *read_buffer = stackbuf;
ptrdiff_t read_buffer_size = sizeof stackbuf;
char *heapbuf = NULL;
@@ -3893,7 +3895,7 @@ read0 (Lisp_Object readcharfun, bool locate_syms)
case '&':
/* #&N"..." -- bool-vector */
- obj = read_bool_vector (stackbuf, readcharfun);
+ obj = read_bool_vector (readcharfun);
break;
case '!':
@@ -3909,17 +3911,17 @@ read0 (Lisp_Object readcharfun, bool locate_syms)
case 'x':
case 'X':
- obj = read_integer (readcharfun, 16, stackbuf);
+ obj = read_integer (readcharfun, 16);
break;
case 'o':
case 'O':
- obj = read_integer (readcharfun, 8, stackbuf);
+ obj = read_integer (readcharfun, 8);
break;
case 'b':
case 'B':
- obj = read_integer (readcharfun, 2, stackbuf);
+ obj = read_integer (readcharfun, 2);
break;
case '@':
@@ -3988,7 +3990,7 @@ read0 (Lisp_Object readcharfun, bool locate_syms)
/* #NrDIGITS -- radix-N number */
if (n < 0 || n > 36)
invalid_radix_integer (n, readcharfun);
- obj = read_integer (readcharfun, n, stackbuf);
+ obj = read_integer (readcharfun, n);
break;
}
else if (n <= MOST_POSITIVE_FIXNUM && !NILP (Vread_circle))
@@ -4043,7 +4045,7 @@ read0 (Lisp_Object readcharfun, bool locate_syms)
break;
case '"':
- obj = read_string_literal (stackbuf, readcharfun);
+ obj = read_string_literal (readcharfun);
break;
case '\'':
diff --git a/src/macuvs.h b/src/macuvs.h
index 4c084156981..7b8c77f0179 100644
--- a/src/macuvs.h
+++ b/src/macuvs.h
@@ -8,29 +8,29 @@
static const unsigned char mac_uvs_table_adobe_japan1_bytes[] =
{
- 0x00, 0x0e, 0x00, 0x01, 0x1f, 0xb2, 0x00, 0x00,
+ 0x00, 0x0e, 0x00, 0x01, 0x1f, 0xb7, 0x00, 0x00,
0x00, 0x0f, 0x0e, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xaf, 0x0e, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xae,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xb3,
0x0e, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x1c, 0x45, 0x0e, 0x01, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x1e, 0xc4, 0x0e, 0x01,
+ 0x01, 0x1c, 0x4a, 0x0e, 0x01, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x1e, 0xc9, 0x0e, 0x01,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f,
- 0x1d, 0x0e, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x1f, 0x3f, 0x0e, 0x01, 0x06, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f, 0x57, 0x0e,
+ 0x22, 0x0e, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x1f, 0x44, 0x0e, 0x01, 0x06, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f, 0x5c, 0x0e,
0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x1f, 0x65, 0x0e, 0x01, 0x08, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x1f, 0x73, 0x0e, 0x01, 0x09,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f, 0x7c,
+ 0x1f, 0x6a, 0x0e, 0x01, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x1f, 0x78, 0x0e, 0x01, 0x09,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f, 0x81,
0x0e, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x1f, 0x85, 0x0e, 0x01, 0x0b, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x1f, 0x8e, 0x0e, 0x01,
+ 0x01, 0x1f, 0x8a, 0x0e, 0x01, 0x0b, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x1f, 0x93, 0x0e, 0x01,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f,
- 0x97, 0x0e, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x1f, 0xa0, 0x0e, 0x01, 0x0e, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f, 0xa9, 0x00,
- 0x00, 0x33, 0xff, 0x00, 0x34, 0x02, 0x35, 0x82,
+ 0x9c, 0x0e, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x1f, 0xa5, 0x0e, 0x01, 0x0e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f, 0xae, 0x00,
+ 0x00, 0x34, 0x00, 0x00, 0x34, 0x02, 0x35, 0x82,
0x00, 0x34, 0x05, 0x3c, 0x1b, 0x00, 0x34, 0x06,
0x43, 0x5a, 0x00, 0x34, 0x27, 0x36, 0x56, 0x00,
0x34, 0x2c, 0x43, 0x5e, 0x00, 0x34, 0x2e, 0x37,
@@ -8349,870 +8349,870 @@ static const unsigned char mac_uvs_table_adobe_japan1_bytes[] =
0x02, 0xb8, 0x17, 0x4f, 0x24, 0x02, 0xb8, 0x1a,
0x37, 0xc6, 0x02, 0xd5, 0x44, 0x36, 0x0a, 0x02,
0xe2, 0x78, 0x37, 0x6b, 0x02, 0xe5, 0x69, 0x36,
- 0x27, 0x02, 0xe6, 0xea, 0x37, 0x92, 0x00, 0x00,
- 0x04, 0xb7, 0x00, 0x34, 0x02, 0x35, 0x81, 0x00,
- 0x4e, 0x08, 0x34, 0x97, 0x00, 0x4e, 0x0e, 0x4e,
- 0x69, 0x00, 0x4e, 0x19, 0x36, 0xb9, 0x00, 0x4e,
- 0x26, 0x4e, 0x6a, 0x00, 0x4e, 0x30, 0x3c, 0x1a,
- 0x00, 0x4e, 0x39, 0x36, 0x5a, 0x00, 0x4e, 0x3b,
- 0x35, 0xf4, 0x00, 0x4e, 0x73, 0x36, 0x90, 0x00,
- 0x4e, 0xa1, 0x36, 0xcf, 0x00, 0x4e, 0xa4, 0x34,
- 0x7f, 0x00, 0x4e, 0xca, 0x35, 0xd4, 0x00, 0x4f,
- 0x34, 0x36, 0xa0, 0x00, 0x4f, 0x4f, 0x35, 0xfc,
- 0x00, 0x4f, 0x60, 0x3c, 0x1c, 0x00, 0x4f, 0x73,
- 0x4e, 0x6c, 0x00, 0x4f, 0x75, 0x34, 0x47, 0x00,
- 0x4f, 0x7f, 0x34, 0x8a, 0x00, 0x4f, 0xae, 0x34,
- 0x46, 0x00, 0x4f, 0xb5, 0x36, 0x1b, 0x00, 0x4f,
- 0xbf, 0x34, 0xc2, 0x00, 0x50, 0x24, 0x36, 0x5f,
- 0x00, 0x50, 0x26, 0x1d, 0xfa, 0x00, 0x50, 0x49,
- 0x34, 0x61, 0x00, 0x50, 0x4f, 0x36, 0xbe, 0x00,
- 0x50, 0x56, 0x4e, 0x6d, 0x00, 0x50, 0x65, 0x34,
- 0x7b, 0x00, 0x50, 0x85, 0x34, 0xd0, 0x00, 0x50,
- 0x91, 0x34, 0x79, 0x00, 0x50, 0xc5, 0x1d, 0xee,
- 0x00, 0x50, 0xca, 0x1f, 0x2e, 0x00, 0x50, 0xcf,
- 0x34, 0xa2, 0x00, 0x50, 0xe7, 0x34, 0x30, 0x00,
- 0x50, 0xed, 0x4e, 0x6e, 0x00, 0x50, 0xf2, 0x52,
- 0xac, 0x00, 0x51, 0x1a, 0x37, 0x16, 0x00, 0x51,
- 0x32, 0x1e, 0x76, 0x00, 0x51, 0x46, 0x34, 0xa5,
- 0x00, 0x51, 0x4d, 0x34, 0x4d, 0x00, 0x51, 0x4e,
- 0x36, 0x7d, 0x00, 0x51, 0x54, 0x10, 0x74, 0x00,
- 0x51, 0x68, 0x36, 0x42, 0x00, 0x51, 0x6b, 0x4e,
- 0x6f, 0x00, 0x51, 0x6c, 0x34, 0x80, 0x00, 0x51,
- 0x77, 0x35, 0xa5, 0x00, 0x51, 0x7c, 0x35, 0xb4,
- 0x00, 0x51, 0x89, 0x1e, 0x87, 0x00, 0x51, 0x8d,
- 0x08, 0x36, 0x00, 0x51, 0x92, 0x36, 0xd6, 0x00,
- 0x51, 0x93, 0x34, 0xd1, 0x00, 0x51, 0x95, 0x10,
- 0x82, 0x00, 0x51, 0xa4, 0x1e, 0x89, 0x00, 0x51,
- 0xac, 0x0c, 0x59, 0x00, 0x51, 0xb4, 0x34, 0x5c,
- 0x00, 0x51, 0xcb, 0x1e, 0x3e, 0x00, 0x51, 0xdb,
- 0x34, 0xd2, 0x00, 0x51, 0xde, 0x4f, 0x53, 0x00,
- 0x51, 0xe1, 0x36, 0xd9, 0x00, 0x51, 0xfd, 0x4e,
- 0x72, 0x00, 0x52, 0x03, 0x36, 0x22, 0x00, 0x52,
- 0x06, 0x34, 0xbb, 0x00, 0x52, 0x24, 0x36, 0xa1,
- 0x00, 0x52, 0x38, 0x35, 0xb5, 0x00, 0x52, 0x4a,
- 0x35, 0xdd, 0x00, 0x52, 0x4d, 0x36, 0x41, 0x00,
- 0x52, 0x64, 0x4e, 0x74, 0x00, 0x52, 0x71, 0x4e,
- 0x75, 0x00, 0x52, 0x72, 0x05, 0xc2, 0x00, 0x52,
- 0x75, 0x1e, 0x2b, 0x00, 0x52, 0x8d, 0x37, 0x1a,
- 0x00, 0x52, 0xc7, 0x36, 0xf6, 0x00, 0x52, 0xc9,
- 0x0e, 0x29, 0x00, 0x52, 0xd7, 0x37, 0x1b, 0x00,
- 0x52, 0xdd, 0x36, 0x05, 0x00, 0x52, 0xe2, 0x36,
- 0x2a, 0x00, 0x52, 0xe4, 0x34, 0x1a, 0x00, 0x52,
- 0xfa, 0x09, 0x07, 0x00, 0x53, 0x00, 0x37, 0xcf,
- 0x00, 0x53, 0x05, 0x36, 0xc3, 0x00, 0x53, 0x07,
- 0x20, 0xd4, 0x00, 0x53, 0x15, 0x1f, 0x2f, 0x00,
- 0x53, 0x16, 0x35, 0x61, 0x00, 0x53, 0x39, 0x36,
- 0xaa, 0x00, 0x53, 0x3f, 0x4e, 0x77, 0x00, 0x53,
- 0x40, 0x34, 0xd4, 0x00, 0x53, 0x4a, 0x36, 0xa2,
- 0x00, 0x53, 0x51, 0x0d, 0x70, 0x00, 0x53, 0x5a,
- 0x36, 0x98, 0x00, 0x53, 0x65, 0x52, 0xf3, 0x00,
- 0x53, 0x71, 0x35, 0x80, 0x00, 0x53, 0x78, 0x35,
- 0x5f, 0x00, 0x53, 0x7f, 0x06, 0xa2, 0x00, 0x53,
- 0xa9, 0x1d, 0xd8, 0x00, 0x53, 0xc9, 0x4f, 0x39,
- 0x00, 0x53, 0xca, 0x35, 0x8e, 0x00, 0x53, 0xce,
- 0x34, 0x8f, 0x00, 0x53, 0xd7, 0x35, 0xf5, 0x00,
- 0x53, 0xdb, 0x1f, 0x2a, 0x00, 0x53, 0xdf, 0x37,
- 0x1f, 0x00, 0x53, 0xe0, 0x53, 0x00, 0x00, 0x53,
- 0xf1, 0x1e, 0x0c, 0x00, 0x53, 0xf2, 0x34, 0x8b,
- 0x00, 0x54, 0x0f, 0x34, 0xc9, 0x00, 0x54, 0x38,
- 0x35, 0x8f, 0x00, 0x54, 0x40, 0x4e, 0x79, 0x00,
- 0x54, 0x48, 0x36, 0x76, 0x00, 0x54, 0x68, 0x09,
- 0x2a, 0x00, 0x54, 0xac, 0x4f, 0x35, 0x00, 0x54,
- 0xb2, 0x35, 0xdc, 0x00, 0x54, 0xe8, 0x1e, 0x17,
- 0x00, 0x55, 0x10, 0x36, 0x83, 0x00, 0x55, 0x33,
- 0x1e, 0x8b, 0x00, 0x55, 0x39, 0x1e, 0x8a, 0x00,
- 0x55, 0x44, 0x1e, 0x32, 0x00, 0x55, 0x46, 0x36,
- 0x06, 0x00, 0x55, 0x53, 0x35, 0xaa, 0x00, 0x55,
- 0x61, 0x38, 0x39, 0x00, 0x55, 0x84, 0x4e, 0x5e,
- 0x00, 0x55, 0x9c, 0x4e, 0x7b, 0x00, 0x55, 0x9d,
- 0x1d, 0xe3, 0x00, 0x55, 0xa9, 0x1f, 0x30, 0x00,
- 0x55, 0xab, 0x35, 0x8b, 0x00, 0x55, 0xb0, 0x1d,
- 0xf0, 0x00, 0x55, 0xe4, 0x1e, 0x8c, 0x00, 0x56,
- 0x05, 0x53, 0x2d, 0x00, 0x56, 0x06, 0x0b, 0x70,
- 0x00, 0x56, 0x09, 0x4e, 0x7d, 0x00, 0x56, 0x32,
- 0x1e, 0x8d, 0x00, 0x56, 0x42, 0x1d, 0xda, 0x00,
- 0x56, 0x4c, 0x1e, 0x29, 0x00, 0x56, 0x68, 0x34,
- 0x15, 0x00, 0x56, 0x74, 0x34, 0xbc, 0x00, 0x56,
- 0x78, 0x1e, 0x52, 0x00, 0x56, 0xa5, 0x1e, 0x8e,
- 0x00, 0x56, 0xae, 0x1f, 0x31, 0x00, 0x56, 0xc0,
- 0x37, 0x24, 0x00, 0x56, 0xc1, 0x34, 0xd7, 0x00,
- 0x56, 0xce, 0x4e, 0x82, 0x00, 0x56, 0xee, 0x4e,
- 0x83, 0x00, 0x57, 0x0d, 0x34, 0xd8, 0x00, 0x57,
- 0x47, 0x34, 0x78, 0x00, 0x57, 0x6a, 0x36, 0x74,
- 0x00, 0x57, 0xce, 0x09, 0xd3, 0x00, 0x57, 0xd6,
- 0x4e, 0x84, 0x00, 0x57, 0xf4, 0x34, 0x98, 0x00,
- 0x58, 0x0b, 0x1e, 0x8f, 0x00, 0x58, 0x19, 0x1f,
- 0x32, 0x00, 0x58, 0x35, 0x1e, 0x49, 0x00, 0x58,
- 0x3d, 0x4e, 0x85, 0x00, 0x58, 0x40, 0x34, 0x48,
- 0x00, 0x58, 0x58, 0x1e, 0x4d, 0x00, 0x58, 0x59,
- 0x4e, 0x86, 0x00, 0x58, 0x5a, 0x1e, 0x42, 0x00,
- 0x58, 0x9c, 0x36, 0x71, 0x00, 0x58, 0xa8, 0x0e,
- 0x7d, 0x00, 0x58, 0xab, 0x34, 0xd9, 0x00, 0x59,
- 0x06, 0x53, 0x7b, 0x00, 0x59, 0x1b, 0x1f, 0x33,
- 0x00, 0x59, 0x27, 0x36, 0x55, 0x00, 0x59, 0x4f,
- 0x4e, 0x87, 0x00, 0x59, 0x51, 0x35, 0xab, 0x00,
- 0x59, 0x53, 0x37, 0xd1, 0x00, 0x59, 0x60, 0x4e,
- 0x89, 0x00, 0x59, 0x62, 0x4e, 0x8a, 0x00, 0x59,
- 0x73, 0x36, 0x04, 0x00, 0x59, 0x84, 0x36, 0xe7,
- 0x00, 0x59, 0xa5, 0x36, 0x4f, 0x00, 0x59, 0xc9,
- 0x34, 0x8c, 0x00, 0x59, 0xda, 0x34, 0xda, 0x00,
- 0x59, 0xec, 0x36, 0xae, 0x00, 0x59, 0xff, 0x35,
- 0xe0, 0x00, 0x5a, 0x1c, 0x37, 0x26, 0x00, 0x5a,
- 0x29, 0x1e, 0x6f, 0x00, 0x5a, 0x36, 0x34, 0xdb,
- 0x00, 0x5a, 0x66, 0x36, 0xb2, 0x00, 0x5a, 0x9b,
- 0x1e, 0x68, 0x00, 0x5a, 0xbe, 0x1e, 0x90, 0x00,
- 0x5a, 0xc2, 0x37, 0x27, 0x00, 0x5a, 0xcc, 0x1d,
- 0xfb, 0x00, 0x5a, 0xda, 0x4e, 0x8b, 0x00, 0x5b,
- 0x5a, 0x4e, 0x8c, 0x00, 0x5b, 0x73, 0x4e, 0x8d,
- 0x00, 0x5b, 0x7c, 0x4e, 0x8e, 0x00, 0x5b, 0xb3,
- 0x34, 0x6d, 0x00, 0x5b, 0xb5, 0x36, 0x07, 0x00,
- 0x5b, 0xc3, 0x37, 0x29, 0x00, 0x5b, 0xd2, 0x35,
- 0x78, 0x00, 0x5b, 0xdb, 0x20, 0xf4, 0x00, 0x5b,
- 0xe7, 0x0c, 0xe1, 0x00, 0x5b, 0xe8, 0x37, 0x42,
- 0x00, 0x5c, 0x06, 0x09, 0x95, 0x00, 0x5c, 0x0a,
- 0x36, 0x4d, 0x00, 0x5c, 0x0b, 0x36, 0x23, 0x00,
- 0x5c, 0x0e, 0x36, 0x8a, 0x00, 0x5c, 0x0f, 0x36,
- 0x09, 0x00, 0x5c, 0x28, 0x1f, 0x34, 0x00, 0x5c,
- 0x51, 0x1d, 0xf2, 0x00, 0x5c, 0x60, 0x1e, 0x4a,
- 0x00, 0x5c, 0x64, 0x34, 0x31, 0x00, 0x5c, 0x6e,
- 0x12, 0x32, 0x00, 0x5d, 0x29, 0x36, 0xc4, 0x00,
- 0x5d, 0x4e, 0x34, 0xdd, 0x00, 0x5d, 0x87, 0x34,
- 0xde, 0x00, 0x5d, 0xb2, 0x3c, 0x2d, 0x00, 0x5d,
- 0xc9, 0x34, 0xdf, 0x00, 0x5d, 0xcc, 0x34, 0x73,
- 0x00, 0x5d, 0xd3, 0x34, 0xe0, 0x00, 0x5d, 0xe1,
- 0x35, 0xff, 0x00, 0x5d, 0xe5, 0x35, 0xc3, 0x00,
- 0x5d, 0xe8, 0x35, 0x92, 0x00, 0x5d, 0xf7, 0x1d,
- 0xff, 0x00, 0x5d, 0xfd, 0x0b, 0x65, 0x00, 0x5e,
- 0x06, 0x36, 0xa3, 0x00, 0x5e, 0x1d, 0x36, 0x77,
- 0x00, 0x5e, 0x30, 0x34, 0x75, 0x00, 0x5e, 0x3d,
- 0x36, 0xd0, 0x00, 0x5e, 0x43, 0x4e, 0x91, 0x00,
- 0x5e, 0x54, 0x37, 0x2d, 0x00, 0x5e, 0x63, 0x36,
- 0xba, 0x00, 0x5e, 0x64, 0x1e, 0x93, 0x00, 0x5e,
- 0x73, 0x36, 0xbb, 0x00, 0x5e, 0x7e, 0x35, 0x84,
- 0x00, 0x5e, 0x96, 0x1e, 0x70, 0x00, 0x5e, 0xa7,
- 0x4e, 0x92, 0x00, 0x5e, 0xad, 0x34, 0xa9, 0x00,
- 0x5e, 0xc9, 0x0f, 0xbf, 0x00, 0x5e, 0xca, 0x4f,
- 0x4f, 0x00, 0x5e, 0xcb, 0x38, 0xae, 0x00, 0x5e,
- 0xcf, 0x1f, 0x36, 0x00, 0x5e, 0xd0, 0x1f, 0x35,
- 0x00, 0x5e, 0xdf, 0x1e, 0x6a, 0x00, 0x5e, 0xe0,
- 0x1e, 0x18, 0x00, 0x5e, 0xe3, 0x37, 0x2f, 0x00,
- 0x5e, 0xf6, 0x34, 0x67, 0x00, 0x5e, 0xf7, 0x34,
- 0xaa, 0x00, 0x5e, 0xfa, 0x34, 0x7c, 0x00, 0x5e,
- 0xfb, 0x35, 0x69, 0x00, 0x5f, 0x0a, 0x36, 0xbc,
- 0x00, 0x5f, 0x2d, 0x34, 0xe1, 0x00, 0x5f, 0x31,
- 0x35, 0xf3, 0x00, 0x5f, 0x38, 0x4e, 0x94, 0x00,
- 0x5f, 0x45, 0x37, 0xce, 0x00, 0x5f, 0x50, 0x3c,
- 0x1f, 0x00, 0x5f, 0x62, 0x4e, 0x5f, 0x00, 0x5f,
- 0x69, 0x35, 0xd7, 0x00, 0x5f, 0x6b, 0x36, 0x68,
- 0x00, 0x5f, 0x80, 0x35, 0x5d, 0x00, 0x5f, 0x98,
- 0x34, 0xe2, 0x00, 0x5f, 0xa1, 0x4e, 0x95, 0x00,
- 0x5f, 0xae, 0x36, 0xa8, 0x00, 0x5f, 0xb5, 0x36,
- 0x69, 0x00, 0x5f, 0xbd, 0x1d, 0xea, 0x00, 0x5f,
- 0xcd, 0x36, 0x91, 0x00, 0x5f, 0xd8, 0x36, 0xd1,
- 0x00, 0x5f, 0xd9, 0x36, 0xd2, 0x00, 0x5f, 0xdd,
- 0x4e, 0x96, 0x00, 0x60, 0x25, 0x35, 0x90, 0x00,
- 0x60, 0x50, 0x35, 0x99, 0x00, 0x60, 0x62, 0x1d,
- 0xe0, 0x00, 0x60, 0x65, 0x34, 0xa4, 0x00, 0x60,
- 0x75, 0x35, 0xac, 0x00, 0x60, 0x94, 0x05, 0x79,
- 0x00, 0x60, 0x97, 0x1e, 0x94, 0x00, 0x60, 0x9e,
- 0x54, 0x36, 0x00, 0x60, 0xa4, 0x3c, 0x20, 0x00,
- 0x60, 0xb2, 0x34, 0xb3, 0x00, 0x60, 0xc5, 0x36,
- 0x12, 0x00, 0x60, 0xd8, 0x34, 0xe3, 0x00, 0x61,
- 0x08, 0x1e, 0x7a, 0x00, 0x61, 0x09, 0x36, 0xf3,
- 0x00, 0x61, 0x0f, 0x35, 0x47, 0x00, 0x61, 0x3d,
- 0x34, 0xe4, 0x00, 0x61, 0x48, 0x4e, 0x60, 0x00,
- 0x61, 0x4c, 0x35, 0xc4, 0x00, 0x61, 0x4e, 0x34,
- 0x2c, 0x00, 0x61, 0x62, 0x4e, 0x97, 0x00, 0x61,
- 0x67, 0x1d, 0xf5, 0x00, 0x61, 0x68, 0x34, 0x10,
- 0x00, 0x61, 0x8e, 0x0b, 0x00, 0x00, 0x61, 0x90,
- 0x37, 0x10, 0x00, 0x61, 0xa4, 0x34, 0xbd, 0x00,
- 0x61, 0xb2, 0x35, 0xb6, 0x00, 0x61, 0xf2, 0x34,
- 0x39, 0x00, 0x61, 0xf8, 0x4e, 0x99, 0x00, 0x61,
- 0xfe, 0x34, 0xe5, 0x00, 0x62, 0x10, 0x36, 0x2b,
- 0x00, 0x62, 0x3b, 0x36, 0xeb, 0x00, 0x62, 0x3f,
- 0x36, 0xd3, 0x00, 0x62, 0x40, 0x36, 0x02, 0x00,
- 0x62, 0x41, 0x1f, 0x37, 0x00, 0x62, 0x47, 0x36,
- 0x3b, 0x00, 0x62, 0x48, 0x1e, 0xc2, 0x00, 0x62,
- 0x49, 0x1e, 0x63, 0x00, 0x62, 0x68, 0x34, 0xe6,
- 0x00, 0x62, 0x71, 0x35, 0x45, 0x00, 0x62, 0xb1,
- 0x36, 0xc5, 0x00, 0x62, 0xcc, 0x37, 0x32, 0x00,
- 0x62, 0xcf, 0x34, 0xe7, 0x00, 0x62, 0xd0, 0x1d,
- 0xe1, 0x00, 0x62, 0xd2, 0x35, 0x93, 0x00, 0x62,
- 0xd4, 0x13, 0x5d, 0x00, 0x62, 0xf3, 0x1f, 0x21,
- 0x00, 0x62, 0xf7, 0x34, 0x88, 0x00, 0x63, 0x3a,
- 0x4f, 0x3e, 0x00, 0x63, 0x3d, 0x1e, 0x62, 0x00,
- 0x63, 0x4c, 0x34, 0x5d, 0x00, 0x63, 0x57, 0x1e,
- 0x3f, 0x00, 0x63, 0x67, 0x34, 0xc3, 0x00, 0x63,
- 0x68, 0x35, 0xec, 0x00, 0x63, 0x69, 0x1e, 0x95,
- 0x00, 0x63, 0x6e, 0x34, 0x9d, 0x00, 0x63, 0x72,
- 0x1d, 0xfc, 0x00, 0x63, 0x83, 0x36, 0x43, 0x00,
- 0x63, 0x88, 0x35, 0xf6, 0x00, 0x63, 0x92, 0x34,
- 0xaf, 0x00, 0x63, 0xa1, 0x35, 0xd8, 0x00, 0x63,
- 0xa7, 0x35, 0xc6, 0x00, 0x63, 0xc3, 0x1f, 0x27,
- 0x00, 0x63, 0xc6, 0x37, 0x34, 0x00, 0x63, 0xf4,
- 0x35, 0x57, 0x00, 0x64, 0x06, 0x1e, 0x96, 0x00,
- 0x64, 0x0f, 0x34, 0xe9, 0x00, 0x64, 0x1c, 0x37,
- 0x33, 0x00, 0x64, 0x28, 0x37, 0x35, 0x00, 0x64,
- 0x42, 0x34, 0x9e, 0x00, 0x64, 0x69, 0x36, 0xd7,
- 0x00, 0x64, 0x6f, 0x4f, 0x28, 0x00, 0x64, 0x7a,
- 0x1e, 0x21, 0x00, 0x64, 0xb0, 0x1e, 0x24, 0x00,
- 0x64, 0xe2, 0x1e, 0x45, 0x00, 0x64, 0xf2, 0x34,
- 0xea, 0x00, 0x64, 0xf6, 0x4e, 0x9e, 0x00, 0x65,
- 0x1d, 0x34, 0xe8, 0x00, 0x65, 0x4f, 0x0d, 0xc4,
- 0x00, 0x65, 0x5d, 0x34, 0xeb, 0x00, 0x65, 0x5e,
- 0x4e, 0xa1, 0x00, 0x65, 0x62, 0x34, 0x71, 0x00,
- 0x65, 0x77, 0x36, 0xb3, 0x00, 0x65, 0x83, 0x1e,
- 0x98, 0x00, 0x65, 0x87, 0x4e, 0xa3, 0x00, 0x65,
- 0x89, 0x4e, 0xa4, 0x00, 0x65, 0x8e, 0x4e, 0xa6,
- 0x00, 0x65, 0x90, 0x34, 0xb5, 0x00, 0x65, 0x9c,
- 0x35, 0xed, 0x00, 0x65, 0xa7, 0x4f, 0x41, 0x00,
- 0x65, 0xbc, 0x35, 0x5c, 0x00, 0x65, 0xc5, 0x37,
- 0x08, 0x00, 0x65, 0xdf, 0x54, 0xbe, 0x00, 0x65,
- 0xe1, 0x4e, 0xa9, 0x00, 0x65, 0xe2, 0x06, 0x37,
- 0x00, 0x66, 0x0e, 0x36, 0xe4, 0x00, 0x66, 0x1e,
- 0x21, 0x1c, 0x00, 0x66, 0x5f, 0x34, 0xec, 0x00,
- 0x66, 0x66, 0x1d, 0xe2, 0x00, 0x66, 0x67, 0x4e,
- 0xaa, 0x00, 0x66, 0x69, 0x36, 0xa5, 0x00, 0x66,
- 0x6e, 0x4e, 0xab, 0x00, 0x66, 0x74, 0x0a, 0x56,
- 0x00, 0x66, 0x77, 0x39, 0x11, 0x00, 0x66, 0x81,
- 0x35, 0xa0, 0x00, 0x66, 0x91, 0x34, 0x28, 0x00,
- 0x66, 0x96, 0x36, 0x5e, 0x00, 0x66, 0x97, 0x35,
- 0x46, 0x00, 0x66, 0xb5, 0x54, 0xda, 0x00, 0x66,
- 0xc1, 0x1f, 0x38, 0x00, 0x66, 0xd9, 0x1e, 0x13,
- 0x00, 0x66, 0xdc, 0x36, 0xfd, 0x00, 0x66, 0xf4,
- 0x34, 0x81, 0x00, 0x66, 0xf5, 0x37, 0x3b, 0x00,
- 0x66, 0xf8, 0x36, 0x03, 0x00, 0x66, 0xfb, 0x37,
- 0xcd, 0x00, 0x66, 0xfc, 0x37, 0x20, 0x00, 0x67,
- 0x00, 0x4e, 0xaf, 0x00, 0x67, 0x08, 0x35, 0xb2,
- 0x00, 0x67, 0x09, 0x36, 0xf7, 0x00, 0x67, 0x0b,
- 0x36, 0xc6, 0x00, 0x67, 0x0d, 0x36, 0xb7, 0x00,
- 0x67, 0x15, 0x36, 0x6f, 0x00, 0x67, 0x17, 0x0f,
- 0xd5, 0x00, 0x67, 0x1b, 0x36, 0xd4, 0x00, 0x67,
- 0x1d, 0x36, 0x6b, 0x00, 0x67, 0x1f, 0x35, 0x86,
- 0x00, 0x67, 0x53, 0x1e, 0x0f, 0x00, 0x67, 0x56,
- 0x4f, 0x3a, 0x00, 0x67, 0x5e, 0x37, 0x3c, 0x00,
- 0x67, 0x61, 0x4e, 0xb0, 0x00, 0x67, 0x7e, 0x34,
- 0x95, 0x00, 0x67, 0xa6, 0x1e, 0x99, 0x00, 0x67,
- 0xa9, 0x34, 0xed, 0x00, 0x67, 0xc4, 0x4e, 0xb1,
- 0x00, 0x67, 0xca, 0x1e, 0x65, 0x00, 0x67, 0xd4,
- 0x34, 0x91, 0x00, 0x67, 0xe7, 0x34, 0xee, 0x00,
- 0x67, 0xf1, 0x36, 0x65, 0x00, 0x68, 0x01, 0x21,
- 0x2e, 0x00, 0x68, 0x02, 0x4e, 0xb2, 0x00, 0x68,
- 0x13, 0x1e, 0x25, 0x00, 0x68, 0x1f, 0x4e, 0x61,
- 0x00, 0x68, 0x21, 0x34, 0x82, 0x00, 0x68, 0x43,
- 0x34, 0xac, 0x00, 0x68, 0x52, 0x21, 0x2c, 0x00,
- 0x68, 0x5d, 0x34, 0xc5, 0x00, 0x68, 0x7a, 0x36,
- 0xf0, 0x00, 0x68, 0x81, 0x37, 0x09, 0x00, 0x68,
- 0x85, 0x0d, 0x15, 0x00, 0x68, 0x8d, 0x37, 0x3e,
- 0x00, 0x68, 0x97, 0x4f, 0x37, 0x00, 0x68, 0x9b,
- 0x1e, 0x9b, 0x00, 0x68, 0x9d, 0x37, 0x3d, 0x00,
- 0x68, 0xa2, 0x1e, 0x19, 0x00, 0x68, 0xc8, 0x37,
- 0xcc, 0x00, 0x68, 0xda, 0x1e, 0x38, 0x00, 0x69,
- 0x0d, 0x34, 0x99, 0x00, 0x69, 0x30, 0x34, 0xf0,
- 0x00, 0x69, 0x3d, 0x4e, 0xb3, 0x00, 0x69, 0x5e,
- 0x4e, 0xb4, 0x00, 0x69, 0x62, 0x1e, 0x58, 0x00,
- 0x69, 0x6b, 0x34, 0xef, 0x00, 0x69, 0x6f, 0x34,
- 0x94, 0x00, 0x69, 0x82, 0x34, 0x5b, 0x00, 0x69,
- 0x8a, 0x1e, 0x06, 0x00, 0x69, 0x94, 0x1e, 0x84,
- 0x00, 0x69, 0xa7, 0x34, 0xf1, 0x00, 0x69, 0xbb,
- 0x37, 0x43, 0x00, 0x69, 0xc1, 0x35, 0x9a, 0x00,
- 0x69, 0xcb, 0x35, 0xc7, 0x00, 0x69, 0xcc, 0x1e,
- 0x40, 0x00, 0x69, 0xd9, 0x36, 0xdd, 0x00, 0x69,
- 0xea, 0x35, 0x6f, 0x00, 0x69, 0xfe, 0x55, 0x1f,
- 0x00, 0x6a, 0x0b, 0x1e, 0x64, 0x00, 0x6a, 0x3d,
- 0x1e, 0x3a, 0x00, 0x6a, 0x44, 0x34, 0xf2, 0x00,
- 0x6a, 0x55, 0x55, 0x25, 0x00, 0x6a, 0x5f, 0x35,
- 0x87, 0x00, 0x6a, 0x73, 0x37, 0xd4, 0x00, 0x6a,
- 0x8e, 0x34, 0x7e, 0x00, 0x6a, 0x90, 0x34, 0xf3,
- 0x00, 0x6a, 0x9c, 0x4e, 0xb6, 0x00, 0x6a, 0xdb,
- 0x06, 0xf3, 0x00, 0x6b, 0x04, 0x0f, 0x5d, 0x00,
- 0x6b, 0x1d, 0x1d, 0xd7, 0x00, 0x6b, 0x21, 0x35,
- 0xe7, 0x00, 0x6b, 0x24, 0x3c, 0x22, 0x00, 0x6b,
- 0x4e, 0x36, 0x5b, 0x00, 0x6b, 0x96, 0x36, 0x16,
- 0x00, 0x6b, 0xba, 0x08, 0x74, 0x00, 0x6b, 0xbb,
- 0x34, 0x70, 0x00, 0x6c, 0x08, 0x1f, 0x39, 0x00,
- 0x6c, 0x13, 0x34, 0xf5, 0x00, 0x6c, 0x38, 0x4e,
- 0xba, 0x00, 0x6c, 0x3a, 0x39, 0x62, 0x00, 0x6c,
- 0x72, 0x1f, 0x1e, 0x00, 0x6c, 0xaa, 0x37, 0x48,
- 0x00, 0x6c, 0xbf, 0x05, 0x0a, 0x00, 0x6c, 0xe1,
- 0x1e, 0x71, 0x00, 0x6c, 0xe8, 0x36, 0x66, 0x00,
- 0x6d, 0x3e, 0x34, 0xae, 0x00, 0x6d, 0x69, 0x35,
- 0xc8, 0x00, 0x6d, 0x6e, 0x36, 0xb4, 0x00, 0x6d,
- 0x77, 0x05, 0x82, 0x00, 0x6d, 0x78, 0x36, 0x1d,
- 0x00, 0x6d, 0x88, 0x36, 0x0c, 0x00, 0x6d, 0xe4,
- 0x4e, 0xbd, 0x00, 0x6d, 0xeb, 0x1d, 0xd5, 0x00,
- 0x6d, 0xfb, 0x36, 0x7c, 0x00, 0x6e, 0x08, 0x4e,
- 0xbf, 0x00, 0x6e, 0x1a, 0x09, 0x77, 0x00, 0x6e,
- 0x23, 0x1f, 0x3a, 0x00, 0x6e, 0x2f, 0x35, 0xc9,
- 0x00, 0x6e, 0x6e, 0x1e, 0x9d, 0x00, 0x6e, 0x72,
- 0x4e, 0xc0, 0x00, 0x6e, 0x7e, 0x34, 0xcf, 0x00,
- 0x6e, 0x9d, 0x1e, 0x01, 0x00, 0x6e, 0xa2, 0x1d,
- 0xd3, 0x00, 0x6e, 0xba, 0x1e, 0x46, 0x00, 0x6e,
- 0xcb, 0x35, 0xe9, 0x00, 0x6e, 0xd5, 0x4e, 0xc2,
- 0x00, 0x6e, 0xdb, 0x4e, 0xc3, 0x00, 0x6e, 0xec,
- 0x1f, 0x3b, 0x00, 0x6e, 0xfe, 0x34, 0xf8, 0x00,
- 0x6f, 0x11, 0x34, 0xf7, 0x00, 0x6f, 0x22, 0x34,
- 0x14, 0x00, 0x6f, 0x23, 0x0f, 0xc2, 0x00, 0x6f,
- 0x3e, 0x34, 0xf9, 0x00, 0x6f, 0x51, 0x36, 0x9e,
- 0x00, 0x6f, 0x54, 0x35, 0xb0, 0x00, 0x6f, 0x5b,
- 0x4e, 0xc4, 0x00, 0x6f, 0x64, 0x4e, 0xc6, 0x00,
- 0x6f, 0x6e, 0x0b, 0xc8, 0x00, 0x6f, 0x74, 0x4e,
- 0xc7, 0x00, 0x6f, 0x98, 0x37, 0x47, 0x00, 0x6f,
- 0xef, 0x1e, 0x33, 0x00, 0x6f, 0xf9, 0x39, 0x95,
- 0x00, 0x70, 0x15, 0x1e, 0x6b, 0x00, 0x70, 0x1b,
- 0x37, 0x4a, 0x00, 0x70, 0x1e, 0x1e, 0x51, 0x00,
- 0x70, 0x26, 0x1e, 0x3d, 0x00, 0x70, 0x27, 0x36,
- 0x57, 0x00, 0x70, 0x4a, 0x39, 0x98, 0x00, 0x70,
- 0x58, 0x1e, 0x57, 0x00, 0x70, 0x70, 0x35, 0x6a,
- 0x00, 0x70, 0x78, 0x4f, 0x2e, 0x00, 0x70, 0x7c,
- 0x1e, 0x10, 0x00, 0x70, 0xad, 0x36, 0x5c, 0x00,
- 0x71, 0x49, 0x0f, 0xc3, 0x00, 0x71, 0x4e, 0x1e,
- 0x26, 0x00, 0x71, 0x52, 0x55, 0xad, 0x00, 0x71,
- 0x59, 0x35, 0x59, 0x00, 0x71, 0x62, 0x37, 0x4b,
- 0x00, 0x71, 0x6e, 0x08, 0xfd, 0x00, 0x71, 0x7d,
- 0x1e, 0x27, 0x00, 0x71, 0x94, 0x1e, 0x7d, 0x00,
- 0x71, 0xb3, 0x39, 0xae, 0x00, 0x71, 0xd0, 0x37,
- 0x0a, 0x00, 0x71, 0xff, 0x34, 0xfa, 0x00, 0x72,
- 0x28, 0x15, 0xdf, 0x00, 0x72, 0x2b, 0x3c, 0x26,
- 0x00, 0x72, 0x35, 0x09, 0x0b, 0x00, 0x72, 0x36,
- 0x34, 0xb9, 0x00, 0x72, 0x3a, 0x4f, 0x46, 0x00,
- 0x72, 0x3b, 0x37, 0x4c, 0x00, 0x72, 0x3e, 0x4e,
- 0xc9, 0x00, 0x72, 0x4c, 0x1e, 0x5b, 0x00, 0x72,
- 0x59, 0x1f, 0x1d, 0x00, 0x72, 0xe1, 0x4f, 0x36,
- 0x00, 0x73, 0x1c, 0x37, 0x4e, 0x00, 0x73, 0x2a,
- 0x0b, 0xb4, 0x00, 0x73, 0x36, 0x36, 0xf8, 0x00,
- 0x73, 0x37, 0x1e, 0x7c, 0x00, 0x73, 0x87, 0x37,
- 0x05, 0x00, 0x73, 0x8b, 0x35, 0xa1, 0x00, 0x73,
- 0xca, 0x1e, 0x0b, 0x00, 0x73, 0xce, 0x1e, 0xa0,
- 0x00, 0x73, 0xe5, 0x34, 0xfb, 0x00, 0x73, 0xed,
- 0x34, 0xb1, 0x00, 0x74, 0x22, 0x0b, 0x56, 0x00,
- 0x74, 0x32, 0x34, 0xfc, 0x00, 0x74, 0x5f, 0x34,
- 0xfd, 0x00, 0x74, 0x62, 0x21, 0x71, 0x00, 0x74,
- 0xb0, 0x35, 0x79, 0x00, 0x74, 0xbd, 0x4e, 0xcd,
- 0x00, 0x74, 0xca, 0x37, 0x4f, 0x00, 0x74, 0xd8,
- 0x55, 0xf6, 0x00, 0x74, 0xdc, 0x35, 0x50, 0x00,
- 0x74, 0xe0, 0x34, 0xfe, 0x00, 0x74, 0xef, 0x55,
- 0xfa, 0x00, 0x75, 0x04, 0x1e, 0xa1, 0x00, 0x75,
- 0x0c, 0x34, 0xff, 0x00, 0x75, 0x0d, 0x1e, 0xa2,
- 0x00, 0x75, 0x11, 0x1e, 0x04, 0x00, 0x75, 0x15,
- 0x1e, 0xa3, 0x00, 0x75, 0x26, 0x4f, 0x3b, 0x00,
- 0x75, 0x54, 0x36, 0xa4, 0x00, 0x75, 0x5d, 0x4e,
- 0xce, 0x00, 0x75, 0xbc, 0x4e, 0xcf, 0x00, 0x75,
- 0xc5, 0x36, 0xb1, 0x00, 0x76, 0x08, 0x4e, 0xd1,
- 0x00, 0x76, 0x26, 0x1e, 0x2d, 0x00, 0x76, 0x52,
- 0x1e, 0x7b, 0x00, 0x76, 0x64, 0x4e, 0xd2, 0x00,
- 0x76, 0x69, 0x4e, 0xd3, 0x00, 0x76, 0x72, 0x35,
- 0x00, 0x00, 0x76, 0x84, 0x36, 0x79, 0x00, 0x76,
- 0x93, 0x1e, 0xa4, 0x00, 0x76, 0xc6, 0x34, 0xc4,
- 0x00, 0x76, 0xca, 0x21, 0x7b, 0x00, 0x76, 0xd4,
- 0x56, 0x1d, 0x00, 0x76, 0xdb, 0x36, 0x2c, 0x00,
- 0x76, 0xdf, 0x36, 0xe5, 0x00, 0x76, 0xf2, 0x36,
- 0xe9, 0x00, 0x76, 0xf4, 0x36, 0x6e, 0x00, 0x77,
- 0x1e, 0x16, 0xb8, 0x00, 0x77, 0x1f, 0x36, 0x1e,
- 0x00, 0x77, 0x37, 0x4e, 0xd5, 0x00, 0x77, 0x3a,
- 0x34, 0xa6, 0x00, 0x77, 0x7e, 0x4e, 0xd6, 0x00,
- 0x77, 0x8d, 0x56, 0x2e, 0x00, 0x77, 0xa2, 0x56,
- 0x2f, 0x00, 0x77, 0xa5, 0x1e, 0x6e, 0x00, 0x77,
- 0xac, 0x34, 0x92, 0x00, 0x77, 0xe9, 0x35, 0xa4,
- 0x00, 0x78, 0x32, 0x36, 0xc7, 0x00, 0x78, 0x3a,
- 0x36, 0x7f, 0x00, 0x78, 0x5d, 0x36, 0x0d, 0x00,
- 0x78, 0x6c, 0x34, 0x83, 0x00, 0x78, 0x7c, 0x1e,
- 0xa5, 0x00, 0x78, 0x91, 0x0d, 0x7e, 0x00, 0x78,
- 0xd4, 0x35, 0x02, 0x00, 0x78, 0xe8, 0x36, 0xda,
- 0x00, 0x78, 0xef, 0x35, 0x4b, 0x00, 0x79, 0x2a,
- 0x35, 0x01, 0x00, 0x79, 0x34, 0x3a, 0x38, 0x00,
- 0x79, 0x3a, 0x08, 0xd4, 0x00, 0x79, 0x3c, 0x21,
- 0x83, 0x00, 0x79, 0x3e, 0x34, 0x24, 0x00, 0x79,
- 0x40, 0x37, 0x57, 0x00, 0x79, 0x41, 0x1d, 0xf4,
- 0x00, 0x79, 0x47, 0x1d, 0xeb, 0x00, 0x79, 0x48,
- 0x06, 0x41, 0x00, 0x79, 0x49, 0x34, 0x21, 0x00,
- 0x79, 0x50, 0x0f, 0x1e, 0x00, 0x79, 0x53, 0x37,
- 0x58, 0x00, 0x79, 0x56, 0x34, 0x2f, 0x00, 0x79,
- 0x5d, 0x09, 0x55, 0x00, 0x79, 0x5e, 0x0a, 0x06,
- 0x00, 0x79, 0x62, 0x1f, 0x29, 0x00, 0x79, 0x65,
- 0x09, 0xb5, 0x00, 0x79, 0x8d, 0x05, 0x52, 0x00,
- 0x79, 0x8e, 0x34, 0x3b, 0x00, 0x79, 0x8f, 0x21,
- 0x87, 0x00, 0x79, 0xa7, 0x4e, 0xd7, 0x00, 0x79,
- 0xae, 0x37, 0x5b, 0x00, 0x79, 0xb0, 0x1e, 0x59,
- 0x00, 0x79, 0xb1, 0x4e, 0xd8, 0x00, 0x79, 0xba,
- 0x35, 0x03, 0x00, 0x79, 0xe4, 0x1e, 0x5d, 0x00,
- 0x7a, 0x0b, 0x36, 0x78, 0x00, 0x7a, 0x17, 0x1e,
- 0x66, 0x00, 0x7a, 0x19, 0x35, 0x04, 0x00, 0x7a,
- 0x31, 0x1e, 0xa6, 0x00, 0x7a, 0x40, 0x08, 0x04,
- 0x00, 0x7a, 0x60, 0x3a, 0x4e, 0x00, 0x7a, 0x74,
- 0x34, 0x7a, 0x00, 0x7a, 0x7a, 0x35, 0xa7, 0x00,
- 0x7a, 0x7f, 0x1f, 0x25, 0x00, 0x7a, 0x81, 0x34,
- 0x3d, 0x00, 0x7a, 0x95, 0x35, 0x05, 0x00, 0x7a,
- 0x97, 0x1f, 0x3c, 0x00, 0x7a, 0xae, 0x34, 0x77,
- 0x00, 0x7a, 0xbe, 0x4e, 0xd9, 0x00, 0x7a, 0xc6,
- 0x3c, 0x27, 0x00, 0x7a, 0xc8, 0x4f, 0x3d, 0x00,
- 0x7b, 0x08, 0x1f, 0x1f, 0x00, 0x7b, 0x51, 0x36,
- 0x63, 0x00, 0x7b, 0x75, 0x4f, 0x2a, 0x00, 0x7b,
- 0x99, 0x1e, 0xa8, 0x00, 0x7b, 0xad, 0x1f, 0x26,
- 0x00, 0x7b, 0xb8, 0x1e, 0x5f, 0x00, 0x7b, 0xc0,
- 0x34, 0x2e, 0x00, 0x7b, 0xc7, 0x1f, 0x2b, 0x00,
- 0x7b, 0xc9, 0x36, 0x61, 0x00, 0x7b, 0xdd, 0x1f,
- 0x3d, 0x00, 0x7b, 0xe0, 0x4e, 0xda, 0x00, 0x7c,
- 0x14, 0x37, 0x5f, 0x00, 0x7c, 0x3e, 0x1f, 0x2d,
- 0x00, 0x7c, 0x3f, 0x36, 0xc2, 0x00, 0x7c, 0x4d,
- 0x36, 0x36, 0x00, 0x7c, 0x50, 0x37, 0x61, 0x00,
- 0x7c, 0x58, 0x37, 0x62, 0x00, 0x7c, 0x69, 0x56,
- 0xaa, 0x00, 0x7c, 0x7e, 0x1e, 0x78, 0x00, 0x7c,
- 0x82, 0x4f, 0x30, 0x00, 0x7c, 0x89, 0x34, 0xbe,
- 0x00, 0x7c, 0x90, 0x1e, 0xa9, 0x00, 0x7c, 0xae,
- 0x1e, 0xaa, 0x00, 0x7c, 0xbe, 0x0a, 0x5e, 0x00,
- 0x7c, 0xd6, 0x0c, 0x76, 0x00, 0x7c, 0xf2, 0x35,
- 0x06, 0x00, 0x7d, 0x04, 0x36, 0xee, 0x00, 0x7d,
- 0x09, 0x4e, 0xdc, 0x00, 0x7d, 0x0b, 0x36, 0xec,
- 0x00, 0x7d, 0x0d, 0x36, 0x94, 0x00, 0x7d, 0x1a,
- 0x35, 0x91, 0x00, 0x7d, 0x1b, 0x34, 0xbf, 0x00,
- 0x7d, 0x42, 0x35, 0xf8, 0x00, 0x7d, 0x46, 0x37,
- 0x63, 0x00, 0x7d, 0x5c, 0x21, 0x90, 0x00, 0x7d,
- 0x5e, 0x34, 0x84, 0x00, 0x7d, 0x63, 0x37, 0x64,
- 0x00, 0x7d, 0x73, 0x35, 0x07, 0x00, 0x7d, 0x9b,
- 0x1e, 0xab, 0x00, 0x7d, 0x9f, 0x1e, 0xad, 0x00,
- 0x7d, 0xae, 0x1e, 0xac, 0x00, 0x7d, 0xb2, 0x4e,
- 0xdd, 0x00, 0x7d, 0xcb, 0x34, 0xb6, 0x00, 0x7d,
- 0xcf, 0x34, 0xa0, 0x00, 0x7d, 0xdd, 0x35, 0x08,
- 0x00, 0x7d, 0xe8, 0x36, 0xbf, 0x00, 0x7d, 0xe9,
- 0x35, 0x7a, 0x00, 0x7d, 0xef, 0x34, 0x62, 0x00,
- 0x7d, 0xf4, 0x0f, 0xc5, 0x00, 0x7e, 0x09, 0x47,
- 0xbe, 0x00, 0x7e, 0x1b, 0x36, 0x9b, 0x00, 0x7e,
- 0x22, 0x37, 0x65, 0x00, 0x7e, 0x2b, 0x36, 0xc8,
- 0x00, 0x7e, 0x35, 0x35, 0x09, 0x00, 0x7e, 0x41,
- 0x34, 0x40, 0x00, 0x7e, 0x43, 0x37, 0x69, 0x00,
- 0x7e, 0x6d, 0x36, 0xe1, 0x00, 0x7e, 0x8c, 0x37,
- 0x6a, 0x00, 0x7f, 0x3e, 0x4e, 0xdf, 0x00, 0x7f,
- 0x50, 0x37, 0x6b, 0x00, 0x7f, 0x61, 0x3c, 0x28,
- 0x00, 0x7f, 0x6a, 0x34, 0x89, 0x00, 0x7f, 0x6e,
- 0x36, 0x60, 0x00, 0x7f, 0x72, 0x09, 0x7a, 0x00,
- 0x7f, 0x80, 0x56, 0xda, 0x00, 0x7f, 0x8a, 0x0f,
- 0x3d, 0x00, 0x7f, 0xa1, 0x36, 0x3d, 0x00, 0x7f,
- 0xae, 0x35, 0x0a, 0x00, 0x7f, 0xbd, 0x04, 0xcb,
- 0x00, 0x7f, 0xc1, 0x34, 0x6a, 0x00, 0x7f, 0xc5,
- 0x37, 0x6f, 0x00, 0x7f, 0xc6, 0x37, 0x70, 0x00,
- 0x7f, 0xcc, 0x37, 0x01, 0x00, 0x7f, 0xd2, 0x35,
- 0xf9, 0x00, 0x7f, 0xd4, 0x1e, 0xae, 0x00, 0x7f,
- 0xe0, 0x1e, 0x20, 0x00, 0x7f, 0xe1, 0x35, 0x0b,
- 0x00, 0x7f, 0xe9, 0x1f, 0x3e, 0x00, 0x7f, 0xeb,
- 0x1d, 0xe9, 0x00, 0x7f, 0xf0, 0x1d, 0xe8, 0x00,
- 0x7f, 0xfb, 0x36, 0xd8, 0x00, 0x7f, 0xfc, 0x34,
- 0xc8, 0x00, 0x80, 0x00, 0x1e, 0x7e, 0x00, 0x80,
- 0x03, 0x34, 0x85, 0x00, 0x80, 0x05, 0x34, 0x25,
- 0x00, 0x80, 0x12, 0x4e, 0xe1, 0x00, 0x80, 0x15,
- 0x35, 0xca, 0x00, 0x80, 0x17, 0x36, 0xea, 0x00,
- 0x80, 0x36, 0x34, 0xc7, 0x00, 0x80, 0x56, 0x36,
- 0x2d, 0x00, 0x80, 0x5a, 0x35, 0x0c, 0x00, 0x80,
- 0x5f, 0x35, 0x0d, 0x00, 0x80, 0x61, 0x34, 0xa1,
- 0x00, 0x80, 0x6f, 0x34, 0xcd, 0x00, 0x80, 0x70,
- 0x35, 0x0f, 0x00, 0x80, 0x71, 0x3c, 0x29, 0x00,
- 0x80, 0x73, 0x35, 0x0e, 0x00, 0x80, 0x74, 0x34,
- 0xa7, 0x00, 0x80, 0x76, 0x35, 0x10, 0x00, 0x80,
- 0x77, 0x34, 0x9a, 0x00, 0x80, 0x7e, 0x34, 0xce,
- 0x00, 0x80, 0x87, 0x36, 0x9c, 0x00, 0x80, 0x89,
- 0x36, 0x8f, 0x00, 0x80, 0x96, 0x36, 0x0e, 0x00,
- 0x80, 0x9e, 0x3c, 0x2a, 0x00, 0x80, 0xa9, 0x35,
- 0xb8, 0x00, 0x80, 0xba, 0x36, 0x97, 0x00, 0x80,
- 0xd6, 0x4e, 0xe3, 0x00, 0x80, 0xde, 0x36, 0xc9,
- 0x00, 0x81, 0x06, 0x36, 0x34, 0x00, 0x81, 0x08,
- 0x34, 0xc6, 0x00, 0x81, 0x09, 0x4e, 0xe4, 0x00,
- 0x81, 0x29, 0x4e, 0xe5, 0x00, 0x81, 0x53, 0x35,
- 0x11, 0x00, 0x81, 0x54, 0x35, 0xcb, 0x00, 0x81,
- 0x70, 0x35, 0xd1, 0x00, 0x81, 0x71, 0x4f, 0x33,
- 0x00, 0x81, 0x7f, 0x1e, 0x30, 0x00, 0x81, 0x8a,
- 0x35, 0x12, 0x00, 0x81, 0xb5, 0x35, 0x13, 0x00,
- 0x81, 0xcd, 0x35, 0x14, 0x00, 0x81, 0xed, 0x34,
- 0x26, 0x00, 0x82, 0x00, 0x57, 0x0f, 0x00, 0x82,
- 0x0c, 0x4e, 0xe6, 0x00, 0x82, 0x18, 0x35, 0x7f,
- 0x00, 0x82, 0x1b, 0x4e, 0xe7, 0x00, 0x82, 0x1c,
- 0x34, 0x93, 0x00, 0x82, 0x1f, 0x35, 0xb3, 0x00,
- 0x82, 0x2e, 0x1e, 0xaf, 0x00, 0x82, 0x39, 0x34,
- 0x9f, 0x00, 0x82, 0x40, 0x4e, 0xe8, 0x00, 0x82,
- 0x47, 0x34, 0xab, 0x00, 0x82, 0x58, 0x37, 0x74,
- 0x00, 0x82, 0x79, 0x37, 0x77, 0x00, 0x82, 0x8d,
- 0x1e, 0xb0, 0x00, 0x82, 0x92, 0x4f, 0x44, 0x00,
- 0x82, 0xa6, 0x1f, 0x19, 0x00, 0x82, 0xb1, 0x35,
- 0x62, 0x00, 0x82, 0xbd, 0x05, 0x6a, 0x00, 0x82,
- 0xc5, 0x35, 0x77, 0x00, 0x82, 0xd2, 0x1e, 0xb1,
- 0x00, 0x82, 0xe3, 0x37, 0x78, 0x00, 0x83, 0x23,
- 0x1e, 0xb2, 0x00, 0x83, 0x28, 0x1f, 0x1a, 0x00,
- 0x83, 0x52, 0x35, 0xcc, 0x00, 0x83, 0x75, 0x1e,
- 0xb3, 0x00, 0x83, 0xbd, 0x37, 0x7c, 0x00, 0x83,
- 0xd3, 0x35, 0x63, 0x00, 0x83, 0xd4, 0x4e, 0xea,
- 0x00, 0x83, 0xdc, 0x35, 0xda, 0x00, 0x83, 0xdf,
- 0x1e, 0x4b, 0x00, 0x83, 0xf2, 0x35, 0x15, 0x00,
- 0x84, 0x0c, 0x36, 0xca, 0x00, 0x84, 0x0f, 0x4e,
- 0xeb, 0x00, 0x84, 0x20, 0x37, 0x7b, 0x00, 0x84,
- 0x22, 0x1f, 0x3f, 0x00, 0x84, 0x57, 0x34, 0x37,
- 0x00, 0x84, 0x5b, 0x1d, 0xe4, 0x00, 0x84, 0x5c,
- 0x57, 0x45, 0x00, 0x84, 0x7a, 0x34, 0xba, 0x00,
- 0x84, 0xea, 0x4e, 0xed, 0x00, 0x84, 0xec, 0x1e,
- 0x72, 0x00, 0x84, 0xee, 0x0f, 0xc7, 0x00, 0x84,
- 0xf4, 0x37, 0x7d, 0x00, 0x85, 0x11, 0x36, 0xbd,
- 0x00, 0x85, 0x17, 0x1e, 0xb4, 0x00, 0x85, 0x3d,
- 0x1e, 0x6d, 0x00, 0x85, 0x43, 0x36, 0xa6, 0x00,
- 0x85, 0x51, 0x4e, 0xef, 0x00, 0x85, 0x55, 0x35,
- 0x16, 0x00, 0x85, 0x5d, 0x57, 0x64, 0x00, 0x85,
- 0x63, 0x4e, 0xf0, 0x00, 0x85, 0x84, 0x36, 0x99,
- 0x00, 0x85, 0x87, 0x37, 0x7f, 0x00, 0x85, 0xa9,
- 0x1e, 0x08, 0x00, 0x85, 0xaf, 0x1e, 0x15, 0x00,
- 0x85, 0xcf, 0x4e, 0xf1, 0x00, 0x85, 0xd5, 0x35,
- 0x17, 0x00, 0x85, 0xe4, 0x36, 0x85, 0x00, 0x85,
- 0xf7, 0x1e, 0x16, 0x00, 0x86, 0x12, 0x21, 0xa4,
- 0x00, 0x86, 0x2d, 0x37, 0x04, 0x00, 0x86, 0x4e,
- 0x4e, 0xf2, 0x00, 0x86, 0x50, 0x35, 0x8c, 0x00,
- 0x86, 0x54, 0x4f, 0x32, 0x00, 0x86, 0x5c, 0x0f,
- 0x82, 0x00, 0x86, 0x5e, 0x35, 0xa6, 0x00, 0x86,
- 0x62, 0x4e, 0xf3, 0x00, 0x86, 0x8a, 0x4e, 0xf4,
- 0x00, 0x86, 0xdb, 0x34, 0x5e, 0x00, 0x86, 0xf8,
- 0x1e, 0x35, 0x00, 0x87, 0x03, 0x4f, 0x48, 0x00,
- 0x87, 0x1a, 0x35, 0x18, 0x00, 0x87, 0x37, 0x37,
- 0x82, 0x00, 0x87, 0x3b, 0x37, 0x83, 0x00, 0x87,
- 0x55, 0x1e, 0x1d, 0x00, 0x87, 0x59, 0x1f, 0x40,
- 0x00, 0x87, 0x82, 0x1e, 0xb6, 0x00, 0x87, 0xa3,
- 0x57, 0xaa, 0x00, 0x87, 0xbd, 0x37, 0x85, 0x00,
- 0x87, 0xd2, 0x1e, 0xb7, 0x00, 0x88, 0x03, 0x3b,
- 0x03, 0x00, 0x88, 0x05, 0x37, 0x84, 0x00, 0x88,
- 0x0e, 0x1f, 0x41, 0x00, 0x88, 0x36, 0x35, 0x19,
- 0x00, 0x88, 0x42, 0x4e, 0xf5, 0x00, 0x88, 0x46,
- 0x35, 0xfa, 0x00, 0x88, 0x4b, 0x57, 0xc3, 0x00,
- 0x88, 0x53, 0x35, 0xfd, 0x00, 0x88, 0x5b, 0x34,
- 0x66, 0x00, 0x88, 0x5e, 0x35, 0x53, 0x00, 0x88,
- 0x63, 0x35, 0x48, 0x00, 0x88, 0x70, 0x36, 0x27,
- 0x00, 0x88, 0x77, 0x4e, 0xf6, 0x00, 0x88, 0x9e,
- 0x35, 0x1a, 0x00, 0x88, 0xd8, 0x35, 0x1b, 0x00,
- 0x88, 0xf4, 0x35, 0x1c, 0x00, 0x89, 0x0a, 0x1e,
- 0xb8, 0x00, 0x89, 0x10, 0x34, 0x13, 0x00, 0x89,
- 0x1c, 0x37, 0xcb, 0x00, 0x89, 0x2b, 0x35, 0x1d,
- 0x00, 0x89, 0x3b, 0x35, 0x1e, 0x00, 0x89, 0x41,
- 0x4e, 0xf7, 0x00, 0x89, 0x56, 0x1d, 0xdd, 0x00,
- 0x89, 0x6a, 0x35, 0x1f, 0x00, 0x89, 0x6f, 0x35,
- 0x20, 0x00, 0x89, 0x81, 0x36, 0xff, 0x00, 0x89,
- 0x86, 0x36, 0xb8, 0x00, 0x89, 0x87, 0x36, 0x95,
- 0x00, 0x89, 0x96, 0x34, 0x22, 0x00, 0x89, 0xaa,
- 0x34, 0x9b, 0x00, 0x89, 0xaf, 0x1e, 0xb9, 0x00,
- 0x89, 0xbd, 0x37, 0x8a, 0x00, 0x89, 0xd2, 0x05,
- 0xaf, 0x00, 0x8a, 0x0a, 0x36, 0x24, 0x00, 0x8a,
- 0x12, 0x37, 0xd7, 0x00, 0x8a, 0x1d, 0x35, 0x21,
- 0x00, 0x8a, 0x1f, 0x34, 0x96, 0x00, 0x8a, 0x3b,
- 0x1e, 0x3c, 0x00, 0x8a, 0x55, 0x36, 0xaf, 0x00,
- 0x8a, 0x6e, 0x1e, 0x28, 0x00, 0x8a, 0x8d, 0x36,
- 0x92, 0x00, 0x8a, 0x95, 0x34, 0xa3, 0x00, 0x8a,
- 0xa0, 0x36, 0x2f, 0x00, 0x8a, 0xa4, 0x35, 0xc2,
- 0x00, 0x8a, 0xb9, 0x34, 0xb7, 0x00, 0x8a, 0xbf,
- 0x36, 0x6d, 0x00, 0x8a, 0xcb, 0x36, 0x30, 0x00,
- 0x8a, 0xdb, 0x37, 0x8b, 0x00, 0x8a, 0xde, 0x1e,
- 0xba, 0x00, 0x8a, 0xed, 0x0f, 0x0b, 0x00, 0x8a,
- 0xee, 0x35, 0xe3, 0x00, 0x8a, 0xf8, 0x09, 0x7e,
- 0x00, 0x8a, 0xfa, 0x1d, 0xfe, 0x00, 0x8b, 0x01,
- 0x04, 0xfc, 0x00, 0x8b, 0x04, 0x36, 0x86, 0x00,
- 0x8b, 0x0e, 0x1e, 0x56, 0x00, 0x8b, 0x19, 0x35,
- 0xb9, 0x00, 0x8b, 0x1b, 0x35, 0xcd, 0x00, 0x8b,
- 0x1d, 0x34, 0x8d, 0x00, 0x8b, 0x2c, 0x1e, 0x69,
- 0x00, 0x8b, 0x39, 0x06, 0xd8, 0x00, 0x8b, 0x3e,
- 0x37, 0x8c, 0x00, 0x8b, 0x41, 0x1e, 0xbb, 0x00,
- 0x8b, 0x56, 0x4e, 0xf8, 0x00, 0x8b, 0x5a, 0x37,
- 0x8d, 0x00, 0x8b, 0x5c, 0x4e, 0xfa, 0x00, 0x8b,
- 0x7f, 0x52, 0x52, 0x00, 0x8c, 0x6a, 0x4e, 0xfd,
- 0x00, 0x8c, 0x79, 0x4e, 0xfe, 0x00, 0x8c, 0x9b,
- 0x58, 0x37, 0x00, 0x8c, 0xa0, 0x36, 0xb5, 0x00,
- 0x8c, 0xa7, 0x34, 0xb8, 0x00, 0x8c, 0xa8, 0x35,
- 0x64, 0x00, 0x8c, 0xab, 0x34, 0x72, 0x00, 0x8c,
- 0xc7, 0x35, 0xe5, 0x00, 0x8c, 0xca, 0x36, 0x4c,
- 0x00, 0x8c, 0xd3, 0x0d, 0xc2, 0x00, 0x8c, 0xed,
- 0x1e, 0x4c, 0x00, 0x8c, 0xfc, 0x34, 0x86, 0x00,
- 0x8d, 0x05, 0x35, 0x22, 0x00, 0x8d, 0x08, 0x34,
- 0x34, 0x00, 0x8d, 0x0f, 0x35, 0x23, 0x00, 0x8d,
- 0x67, 0x4f, 0x00, 0x00, 0x8d, 0x70, 0x36, 0x46,
- 0x00, 0x8d, 0x73, 0x37, 0x8e, 0x00, 0x8d, 0x77,
- 0x35, 0x88, 0x00, 0x8d, 0x99, 0x37, 0x8f, 0x00,
- 0x8d, 0xda, 0x1e, 0xbc, 0x00, 0x8d, 0xdd, 0x35,
- 0x94, 0x00, 0x8d, 0xf3, 0x34, 0xa8, 0x00, 0x8e,
- 0x09, 0x1e, 0xbd, 0x00, 0x8e, 0x34, 0x37, 0x91,
- 0x00, 0x8e, 0x4a, 0x37, 0x92, 0x00, 0x8e, 0x8d,
- 0x36, 0xef, 0x00, 0x8e, 0x91, 0x35, 0x25, 0x00,
- 0x8e, 0xa1, 0x35, 0x26, 0x00, 0x8e, 0xcc, 0x34,
- 0x76, 0x00, 0x8e, 0xd4, 0x3b, 0x4a, 0x00, 0x8f,
- 0x03, 0x4f, 0x02, 0x00, 0x8f, 0x13, 0x1e, 0xbe,
- 0x00, 0x8f, 0x29, 0x34, 0xb0, 0x00, 0x8f, 0x2f,
- 0x34, 0x90, 0x00, 0x8f, 0x38, 0x36, 0xf5, 0x00,
- 0x8f, 0x44, 0x35, 0x75, 0x00, 0x8f, 0xb6, 0x3c,
- 0x2b, 0x00, 0x8f, 0xbb, 0x20, 0x4b, 0x00, 0x8f,
- 0xbc, 0x35, 0xd3, 0x00, 0x8f, 0xbf, 0x1e, 0x37,
- 0x00, 0x8f, 0xc2, 0x1d, 0xd6, 0x00, 0x8f, 0xc4,
- 0x1f, 0x2c, 0x00, 0x8f, 0xc5, 0x36, 0x26, 0x00,
- 0x8f, 0xc6, 0x3b, 0x51, 0x00, 0x8f, 0xce, 0x35,
- 0xae, 0x00, 0x8f, 0xd1, 0x35, 0xa2, 0x00, 0x8f,
- 0xd4, 0x36, 0xc0, 0x00, 0x8f, 0xe6, 0x1d, 0xdf,
- 0x00, 0x8f, 0xe9, 0x1e, 0xc0, 0x00, 0x8f, 0xea,
- 0x1e, 0xbf, 0x00, 0x8f, 0xeb, 0x36, 0x9a, 0x00,
- 0x8f, 0xed, 0x36, 0x7b, 0x00, 0x8f, 0xef, 0x37,
- 0x93, 0x00, 0x8f, 0xf0, 0x35, 0xfe, 0x00, 0x8f,
- 0xf6, 0x4f, 0x06, 0x00, 0x8f, 0xf7, 0x36, 0xe6,
- 0x00, 0x8f, 0xfa, 0x37, 0x95, 0x00, 0x8f, 0xfd,
- 0x36, 0x72, 0x00, 0x90, 0x00, 0x36, 0x51, 0x00,
- 0x90, 0x01, 0x36, 0x47, 0x00, 0x90, 0x03, 0x34,
- 0xad, 0x00, 0x90, 0x06, 0x35, 0x8d, 0x00, 0x90,
- 0x0e, 0x35, 0x28, 0x00, 0x90, 0x0f, 0x36, 0x88,
- 0x00, 0x90, 0x10, 0x36, 0x64, 0x00, 0x90, 0x14,
- 0x36, 0x7e, 0x00, 0x90, 0x17, 0x1e, 0x1f, 0x00,
- 0x90, 0x19, 0x1e, 0x5c, 0x00, 0x90, 0x1a, 0x36,
- 0x73, 0x00, 0x90, 0x1d, 0x1e, 0x22, 0x00, 0x90,
- 0x1e, 0x37, 0x96, 0x00, 0x90, 0x1f, 0x36, 0x4b,
- 0x00, 0x90, 0x20, 0x36, 0x49, 0x00, 0x90, 0x22,
- 0x20, 0x4a, 0x00, 0x90, 0x23, 0x0f, 0xc8, 0x00,
- 0x90, 0x2e, 0x36, 0x52, 0x00, 0x90, 0x31, 0x35,
- 0xfb, 0x00, 0x90, 0x32, 0x36, 0x1f, 0x00, 0x90,
- 0x35, 0x37, 0x97, 0x00, 0x90, 0x38, 0x34, 0x08,
- 0x00, 0x90, 0x39, 0x36, 0x58, 0x00, 0x90, 0x3c,
- 0x1e, 0x67, 0x00, 0x90, 0x41, 0x1e, 0x53, 0x00,
- 0x90, 0x42, 0x34, 0x9c, 0x00, 0x90, 0x47, 0x35,
- 0xa8, 0x00, 0x90, 0x4a, 0x36, 0xfc, 0x00, 0x90,
- 0x4b, 0x35, 0x51, 0x00, 0x90, 0x4d, 0x36, 0xc1,
- 0x00, 0x90, 0x4e, 0x35, 0x65, 0x00, 0x90, 0x50,
- 0x37, 0x98, 0x00, 0x90, 0x52, 0x35, 0x27, 0x00,
- 0x90, 0x53, 0x36, 0x8b, 0x00, 0x90, 0x54, 0x36,
- 0x58, 0x00, 0x90, 0x55, 0x34, 0x63, 0x00, 0x90,
- 0x58, 0x1e, 0xc1, 0x00, 0x90, 0x5c, 0x1e, 0x2e,
- 0x00, 0x90, 0x60, 0x35, 0x5a, 0x00, 0x90, 0x61,
- 0x1e, 0x2a, 0x00, 0x90, 0x63, 0x35, 0xba, 0x00,
- 0x90, 0x69, 0x36, 0x7a, 0x00, 0x90, 0x6d, 0x36,
- 0x48, 0x00, 0x90, 0x6e, 0x1e, 0x0e, 0x00, 0x90,
- 0x75, 0x36, 0x00, 0x00, 0x90, 0x77, 0x36, 0x40,
- 0x00, 0x90, 0x78, 0x36, 0x3f, 0x00, 0x90, 0x7a,
- 0x35, 0x4a, 0x00, 0x90, 0x7c, 0x1e, 0x80, 0x00,
- 0x90, 0x7f, 0x36, 0xa7, 0x00, 0x90, 0x81, 0x37,
- 0x9a, 0x00, 0x90, 0x83, 0x37, 0x5c, 0x00, 0x90,
- 0x84, 0x35, 0x7c, 0x00, 0x90, 0x87, 0x37, 0x94,
- 0x00, 0x90, 0x89, 0x34, 0x5f, 0x00, 0x90, 0x8a,
- 0x37, 0x9b, 0x00, 0x90, 0xa3, 0x1e, 0x55, 0x00,
- 0x90, 0xa6, 0x36, 0xcb, 0x00, 0x90, 0xa8, 0x4f,
- 0x0b, 0x00, 0x90, 0xaa, 0x34, 0x8e, 0x00, 0x90,
- 0xf7, 0x35, 0x9d, 0x00, 0x90, 0xfd, 0x0c, 0x4e,
- 0x00, 0x91, 0x2d, 0x1e, 0x44, 0x00, 0x91, 0x30,
- 0x35, 0x29, 0x00, 0x91, 0x4b, 0x1e, 0x12, 0x00,
- 0x91, 0x4c, 0x35, 0xf2, 0x00, 0x91, 0x4d, 0x4f,
- 0x0c, 0x00, 0x91, 0x56, 0x35, 0x2a, 0x00, 0x91,
- 0x58, 0x35, 0x2b, 0x00, 0x91, 0x65, 0x35, 0x2c,
- 0x00, 0x91, 0x72, 0x35, 0x2e, 0x00, 0x91, 0x73,
- 0x35, 0x2d, 0x00, 0x91, 0x77, 0x35, 0xd0, 0x00,
- 0x91, 0xa2, 0x35, 0x2f, 0x00, 0x91, 0xaa, 0x35,
- 0x31, 0x00, 0x91, 0xaf, 0x35, 0x30, 0x00, 0x91,
- 0xb1, 0x36, 0x9f, 0x00, 0x91, 0xb4, 0x35, 0x32,
- 0x00, 0x91, 0xba, 0x35, 0x33, 0x00, 0x91, 0xc1,
- 0x1e, 0xc3, 0x00, 0x91, 0xc7, 0x1e, 0x05, 0x00,
- 0x91, 0xdc, 0x4f, 0x42, 0x00, 0x91, 0xe3, 0x36,
- 0x75, 0x00, 0x91, 0xfc, 0x3c, 0x2c, 0x00, 0x92,
- 0x37, 0x34, 0x7d, 0x00, 0x92, 0x5b, 0x34, 0x69,
- 0x00, 0x92, 0xe9, 0x4f, 0x0d, 0x00, 0x93, 0x06,
- 0x1e, 0x0a, 0x00, 0x93, 0x35, 0x4f, 0x0e, 0x00,
- 0x93, 0x65, 0x3b, 0x86, 0x00, 0x93, 0x75, 0x4f,
- 0x34, 0x00, 0x93, 0x8b, 0x4f, 0x0f, 0x00, 0x93,
- 0x8c, 0x35, 0x76, 0x00, 0x93, 0x96, 0x35, 0xd5,
- 0x00, 0x93, 0x9a, 0x1e, 0x41, 0x00, 0x93, 0xa1,
- 0x59, 0x04, 0x00, 0x93, 0xae, 0x34, 0x3a, 0x00,
- 0x93, 0xdd, 0x37, 0xae, 0x00, 0x94, 0x3a, 0x4f,
- 0x10, 0x00, 0x94, 0x53, 0x1e, 0x79, 0x00, 0x94,
- 0x77, 0x35, 0x34, 0x00, 0x95, 0x92, 0x35, 0x7d,
- 0x00, 0x95, 0xab, 0x3b, 0x9a, 0x00, 0x95, 0xbb,
- 0x1e, 0xc4, 0x00, 0x95, 0xbc, 0x37, 0xaf, 0x00,
- 0x95, 0xcd, 0x4f, 0x11, 0x00, 0x96, 0x2a, 0x4f,
- 0x12, 0x00, 0x96, 0x4d, 0x34, 0x87, 0x00, 0x96,
- 0x86, 0x34, 0x51, 0x00, 0x96, 0x8a, 0x36, 0x53,
- 0x00, 0x96, 0x94, 0x35, 0x73, 0x00, 0x96, 0x98,
- 0x35, 0x35, 0x00, 0x96, 0x99, 0x4f, 0x31, 0x00,
- 0x96, 0xa3, 0x34, 0xca, 0x00, 0x96, 0xa7, 0x4f,
- 0x14, 0x00, 0x96, 0xb2, 0x37, 0xb1, 0x00, 0x96,
- 0xbb, 0x36, 0x35, 0x00, 0x96, 0xc5, 0x34, 0x6c,
- 0x00, 0x96, 0xc7, 0x35, 0xbe, 0x00, 0x96, 0xd9,
- 0x34, 0xd5, 0x00, 0x96, 0xda, 0x59, 0x3b, 0x00,
- 0x96, 0xe3, 0x0c, 0xc9, 0x00, 0x96, 0xe8, 0x35,
- 0x4d, 0x00, 0x96, 0xea, 0x36, 0x39, 0x00, 0x96,
- 0xf0, 0x34, 0xc0, 0x00, 0x97, 0x21, 0x59, 0x41,
- 0x00, 0x97, 0x24, 0x1e, 0xc6, 0x00, 0x97, 0x3d,
- 0x35, 0x36, 0x00, 0x97, 0x55, 0x21, 0xf8, 0x00,
- 0x97, 0x56, 0x21, 0x8b, 0x00, 0x97, 0x59, 0x37,
- 0xb2, 0x00, 0x97, 0x5c, 0x36, 0x31, 0x00, 0x97,
- 0x60, 0x1e, 0xc7, 0x00, 0x97, 0x6d, 0x1e, 0xc8,
- 0x00, 0x97, 0x71, 0x1e, 0x1e, 0x00, 0x97, 0x74,
- 0x1d, 0xf3, 0x00, 0x97, 0x84, 0x1d, 0xe5, 0x00,
- 0x97, 0x98, 0x1e, 0x1c, 0x00, 0x97, 0xad, 0x4f,
- 0x43, 0x00, 0x97, 0xd3, 0x35, 0x7e, 0x00, 0x97,
- 0xde, 0x3c, 0x2e, 0x00, 0x97, 0xf3, 0x35, 0x60,
- 0x00, 0x97, 0xff, 0x34, 0x19, 0x00, 0x98, 0x0c,
- 0x35, 0x39, 0x00, 0x98, 0x11, 0x34, 0x74, 0x00,
- 0x98, 0x12, 0x34, 0xb2, 0x00, 0x98, 0x13, 0x1e,
- 0x54, 0x00, 0x98, 0x24, 0x1e, 0xc9, 0x00, 0x98,
- 0x3b, 0x0d, 0xc3, 0x00, 0x98, 0x5e, 0x0f, 0xa8,
- 0x00, 0x98, 0x67, 0x35, 0xbf, 0x00, 0x98, 0x73,
- 0x35, 0x3a, 0x00, 0x98, 0xc3, 0x35, 0x3b, 0x00,
- 0x98, 0xdf, 0x36, 0x17, 0x00, 0x98, 0xe2, 0x35,
- 0x89, 0x00, 0x98, 0xeb, 0x37, 0xb4, 0x00, 0x98,
- 0xef, 0x0d, 0x67, 0x00, 0x98, 0xf4, 0x1d, 0xd2,
- 0x00, 0x98, 0xfc, 0x21, 0xfc, 0x00, 0x98, 0xfd,
- 0x36, 0xcd, 0x00, 0x98, 0xfe, 0x36, 0x14, 0x00,
- 0x99, 0x03, 0x37, 0xb5, 0x00, 0x99, 0x05, 0x1e,
- 0x77, 0x00, 0x99, 0x09, 0x37, 0xb6, 0x00, 0x99,
- 0x0a, 0x37, 0x00, 0x00, 0x99, 0x0c, 0x1d, 0xdb,
- 0x00, 0x99, 0x10, 0x1f, 0x22, 0x00, 0x99, 0x13,
- 0x35, 0x68, 0x00, 0x99, 0x21, 0x4f, 0x18, 0x00,
- 0x99, 0x28, 0x21, 0xfe, 0x00, 0x99, 0x45, 0x37,
- 0xb7, 0x00, 0x99, 0x4b, 0x37, 0xb9, 0x00, 0x99,
- 0x57, 0x1f, 0x20, 0x00, 0x99, 0xc1, 0x4f, 0x40,
- 0x00, 0x99, 0xd0, 0x36, 0x67, 0x00, 0x9a, 0x19,
- 0x1f, 0x43, 0x00, 0x9a, 0x30, 0x36, 0x89, 0x00,
- 0x9a, 0x45, 0x35, 0x3c, 0x00, 0x9a, 0x4a, 0x59,
- 0x88, 0x00, 0x9a, 0x5f, 0x37, 0xbb, 0x00, 0x9a,
- 0x65, 0x37, 0xbc, 0x00, 0x9a, 0xef, 0x37, 0xbd,
- 0x00, 0x9b, 0x18, 0x37, 0xbe, 0x00, 0x9b, 0x2d,
- 0x34, 0x3c, 0x00, 0x9b, 0x2e, 0x1e, 0xca, 0x00,
- 0x9b, 0x35, 0x59, 0xa4, 0x00, 0x9b, 0x4d, 0x35,
- 0x3d, 0x00, 0x9b, 0x54, 0x36, 0xdb, 0x00, 0x9b,
- 0x58, 0x35, 0x3e, 0x00, 0x9b, 0x97, 0x1e, 0xcb,
- 0x00, 0x9b, 0xa8, 0x4f, 0x1a, 0x00, 0x9b, 0xab,
- 0x4f, 0x38, 0x00, 0x9b, 0xae, 0x4f, 0x1b, 0x00,
- 0x9b, 0xb9, 0x4f, 0x1c, 0x00, 0x9b, 0xc6, 0x35,
- 0x3f, 0x00, 0x9b, 0xd6, 0x1e, 0x09, 0x00, 0x9b,
- 0xdb, 0x36, 0x54, 0x00, 0x9b, 0xe1, 0x35, 0x40,
- 0x00, 0x9b, 0xf1, 0x35, 0x41, 0x00, 0x9b, 0xf2,
- 0x1e, 0xcc, 0x00, 0x9c, 0x08, 0x4f, 0x1d, 0x00,
- 0x9c, 0x24, 0x4f, 0x1e, 0x00, 0x9c, 0x2f, 0x1d,
- 0xd4, 0x00, 0x9c, 0x3b, 0x4f, 0x1f, 0x00, 0x9c,
- 0x48, 0x1e, 0x39, 0x00, 0x9c, 0x52, 0x1e, 0x74,
- 0x00, 0x9c, 0x57, 0x37, 0x0c, 0x00, 0x9c, 0xe6,
- 0x4f, 0x21, 0x00, 0x9d, 0x07, 0x1e, 0x4f, 0x00,
- 0x9d, 0x08, 0x37, 0xc1, 0x00, 0x9d, 0x09, 0x37,
- 0xc0, 0x00, 0x9d, 0x48, 0x35, 0x42, 0x00, 0x9d,
- 0x60, 0x1e, 0x03, 0x00, 0x9d, 0x6c, 0x36, 0xce,
- 0x00, 0x9d, 0xb4, 0x0b, 0xfd, 0x00, 0x9d, 0xbf,
- 0x59, 0xde, 0x00, 0x9d, 0xc0, 0x4f, 0x22, 0x00,
- 0x9d, 0xc2, 0x4f, 0x23, 0x00, 0x9d, 0xcf, 0x35,
- 0x43, 0x00, 0x9e, 0x97, 0x34, 0xcc, 0x00, 0x9e,
- 0x9f, 0x34, 0xcb, 0x00, 0x9e, 0xa5, 0x37, 0xc2,
- 0x00, 0x9e, 0xaa, 0x1e, 0xcd, 0x00, 0x9e, 0xad,
- 0x1f, 0x44, 0x00, 0x9e, 0xbb, 0x36, 0xdc, 0x00,
- 0x9e, 0xbf, 0x36, 0xe2, 0x00, 0x9e, 0xcc, 0x37,
- 0xc3, 0x00, 0x9e, 0xdb, 0x1e, 0x31, 0x00, 0x9f,
- 0x08, 0x35, 0x44, 0x00, 0x9f, 0x3b, 0x36, 0xa9,
- 0x00, 0x9f, 0x4a, 0x37, 0xc5, 0x00, 0x9f, 0x4b,
- 0x37, 0x5a, 0x00, 0x9f, 0x4e, 0x35, 0x24, 0x00,
- 0x9f, 0x67, 0x37, 0xc7, 0x00, 0x9f, 0x8d, 0x37,
- 0x06, 0x00, 0x9f, 0x9c, 0x1e, 0xce, 0x00, 0x9f,
- 0x9d, 0x1e, 0xa7, 0x00, 0xfa, 0x11, 0x20, 0xfb,
- 0x00, 0xfa, 0x24, 0x21, 0xb8, 0x02, 0x35, 0xc4,
- 0x3c, 0x44, 0x02, 0x36, 0x3a, 0x35, 0x9b, 0x02,
- 0x38, 0x3d, 0x4f, 0x26, 0x02, 0x42, 0xee, 0x37,
- 0xc9, 0x02, 0x62, 0x70, 0x37, 0x6e, 0x02, 0x9d,
- 0x4b, 0x35, 0x96, 0x02, 0x9e, 0x3d, 0x3c, 0x4d,
- 0x02, 0xa6, 0x1a, 0x37, 0xc8, 0x00, 0x00, 0x00,
- 0x7f, 0x00, 0x34, 0x02, 0x35, 0x83, 0x00, 0x50,
- 0x91, 0x35, 0xaf, 0x00, 0x50, 0xca, 0x37, 0x15,
- 0x00, 0x51, 0x54, 0x37, 0x17, 0x00, 0x51, 0x95,
- 0x37, 0x18, 0x00, 0x51, 0xb4, 0x35, 0xdb, 0x00,
- 0x51, 0xde, 0x38, 0x10, 0x00, 0x52, 0x72, 0x4e,
- 0x76, 0x00, 0x53, 0x7f, 0x1d, 0xed, 0x00, 0x53,
- 0xa9, 0x1f, 0x1c, 0x00, 0x55, 0x33, 0x37, 0x21,
- 0x00, 0x55, 0xa9, 0x34, 0xd6, 0x00, 0x55, 0xab,
- 0x4e, 0x7c, 0x00, 0x55, 0xe4, 0x37, 0x22, 0x00,
- 0x56, 0xae, 0x4e, 0x7e, 0x00, 0x57, 0xf4, 0x36,
- 0x13, 0x00, 0x58, 0x5a, 0x20, 0xe6, 0x00, 0x59,
- 0x51, 0x4e, 0x88, 0x00, 0x59, 0xff, 0x35, 0xe1,
- 0x00, 0x5a, 0xbe, 0x34, 0xdc, 0x00, 0x5b, 0xb3,
- 0x35, 0x6b, 0x00, 0x5c, 0x0a, 0x36, 0x4e, 0x00,
- 0x5c, 0x0f, 0x36, 0x0a, 0x00, 0x5e, 0xca, 0x34,
- 0x59, 0x00, 0x5e, 0xe3, 0x4e, 0x93, 0x00, 0x5e,
- 0xf6, 0x35, 0x56, 0x00, 0x60, 0x62, 0x4f, 0x2d,
- 0x00, 0x60, 0x97, 0x37, 0x30, 0x00, 0x61, 0x67,
- 0x35, 0xad, 0x00, 0x61, 0x68, 0x34, 0x6e, 0x00,
- 0x61, 0xb2, 0x4e, 0x98, 0x00, 0x61, 0xf2, 0x36,
- 0x6a, 0x00, 0x62, 0x49, 0x34, 0xb4, 0x00, 0x66,
- 0x5f, 0x37, 0x38, 0x00, 0x66, 0xc1, 0x4e, 0xac,
- 0x00, 0x67, 0x15, 0x36, 0x70, 0x00, 0x67, 0x17,
- 0x21, 0x29, 0x00, 0x67, 0x1b, 0x36, 0xd5, 0x00,
- 0x68, 0x5d, 0x36, 0xde, 0x00, 0x68, 0x7a, 0x36,
- 0xf1, 0x00, 0x69, 0x0d, 0x36, 0x15, 0x00, 0x69,
- 0x82, 0x34, 0x6f, 0x00, 0x6a, 0xdb, 0x35, 0xa9,
- 0x00, 0x6b, 0x21, 0x35, 0xe8, 0x00, 0x6c, 0x08,
- 0x34, 0xf4, 0x00, 0x6c, 0xaa, 0x4e, 0xbb, 0x00,
- 0x6c, 0xbf, 0x34, 0x68, 0x00, 0x6c, 0xe8, 0x32,
- 0x45, 0x00, 0x6d, 0x3e, 0x36, 0x96, 0x00, 0x6e,
- 0x23, 0x34, 0xf6, 0x00, 0x6e, 0xa2, 0x52, 0x4f,
- 0x00, 0x6e, 0xcb, 0x4e, 0xc1, 0x00, 0x6f, 0x11,
- 0x37, 0x45, 0x00, 0x6f, 0x5b, 0x4e, 0xc5, 0x00,
- 0x71, 0x7d, 0x1f, 0x24, 0x00, 0x72, 0x35, 0x35,
- 0xf0, 0x00, 0x73, 0x36, 0x36, 0xf9, 0x00, 0x73,
- 0x37, 0x36, 0xfa, 0x00, 0x73, 0xca, 0x4e, 0xcc,
- 0x00, 0x75, 0x11, 0x35, 0xd2, 0x00, 0x75, 0x15,
- 0x4f, 0x2b, 0x00, 0x79, 0x53, 0x37, 0x59, 0x00,
- 0x7a, 0x74, 0x35, 0xb1, 0x00, 0x7b, 0x08, 0x4f,
- 0x27, 0x00, 0x7b, 0xc0, 0x36, 0x37, 0x00, 0x7c,
- 0x3e, 0x4f, 0x29, 0x00, 0x7c, 0x50, 0x4e, 0xdb,
- 0x00, 0x7c, 0x7e, 0x4f, 0x45, 0x00, 0x7d, 0xb2,
- 0x4e, 0xde, 0x00, 0x7e, 0x22, 0x37, 0x66, 0x00,
- 0x7e, 0x35, 0x37, 0x68, 0x00, 0x7f, 0xc1, 0x35,
- 0x5e, 0x00, 0x7f, 0xe1, 0x4e, 0xe0, 0x00, 0x7f,
- 0xe9, 0x37, 0x71, 0x00, 0x7f, 0xfc, 0x37, 0x02,
- 0x00, 0x81, 0x08, 0x36, 0xe3, 0x00, 0x82, 0x39,
- 0x36, 0x3e, 0x00, 0x82, 0x79, 0x37, 0x76, 0x00,
- 0x82, 0xbd, 0x34, 0x6b, 0x00, 0x83, 0xdf, 0x1f,
- 0x28, 0x00, 0x85, 0x3d, 0x34, 0xc1, 0x00, 0x86,
- 0x12, 0x52, 0x51, 0x00, 0x87, 0xd2, 0x1f, 0x42,
- 0x00, 0x88, 0x05, 0x4f, 0x47, 0x00, 0x88, 0x36,
- 0x37, 0x87, 0x00, 0x8a, 0x0a, 0x36, 0x25, 0x00,
- 0x8a, 0x1d, 0x4f, 0x2c, 0x00, 0x8a, 0x95, 0x36,
- 0x5d, 0x00, 0x8a, 0xee, 0x35, 0xe4, 0x00, 0x8b,
- 0x56, 0x4e, 0xf9, 0x00, 0x8c, 0xa0, 0x36, 0xb6,
- 0x00, 0x8c, 0xc7, 0x35, 0xe6, 0x00, 0x8c, 0xca,
- 0x4e, 0xff, 0x00, 0x8c, 0xfc, 0x35, 0xce, 0x00,
- 0x8f, 0x44, 0x4f, 0x03, 0x00, 0x8f, 0xc5, 0x4f,
- 0x04, 0x00, 0x8f, 0xd4, 0x4f, 0x05, 0x00, 0x90,
- 0x03, 0x36, 0x87, 0x00, 0x90, 0x22, 0x34, 0x60,
- 0x00, 0x90, 0x38, 0x21, 0xb9, 0x00, 0x90, 0x41,
- 0x4f, 0x3f, 0x00, 0x90, 0x42, 0x36, 0x28, 0x00,
- 0x90, 0x55, 0x35, 0x49, 0x00, 0x90, 0x75, 0x36,
- 0x01, 0x00, 0x90, 0x77, 0x4f, 0x07, 0x00, 0x90,
- 0x89, 0x37, 0xa1, 0x00, 0x90, 0x8a, 0x37, 0x9c,
- 0x00, 0x90, 0xa6, 0x36, 0xcc, 0x00, 0x90, 0xaa,
- 0x35, 0xee, 0x00, 0x92, 0x5b, 0x35, 0x5b, 0x00,
- 0x96, 0x86, 0x21, 0xee, 0x00, 0x96, 0x98, 0x4f,
- 0x13, 0x00, 0x96, 0xa3, 0x37, 0x0b, 0x00, 0x96,
- 0xc5, 0x35, 0x67, 0x00, 0x97, 0x5c, 0x36, 0x32,
- 0x00, 0x97, 0x60, 0x35, 0x37, 0x00, 0x97, 0x6d,
- 0x1f, 0x23, 0x00, 0x97, 0x71, 0x35, 0x38, 0x00,
- 0x97, 0xff, 0x35, 0x9e, 0x00, 0x98, 0xef, 0x4f,
- 0x25, 0x00, 0x99, 0x0c, 0x34, 0x65, 0x00, 0x99,
- 0x45, 0x37, 0xb8, 0x00, 0x99, 0x57, 0x35, 0x9f,
- 0x00, 0x9e, 0x9f, 0x37, 0x0d, 0x00, 0x9f, 0x08,
- 0x37, 0xc4, 0x00, 0x9f, 0x8d, 0x37, 0x07, 0x02,
- 0x36, 0x3a, 0x35, 0x9c, 0x00, 0x00, 0x00, 0x11,
- 0x00, 0x51, 0xde, 0x4e, 0x71, 0x00, 0x53, 0xa9,
- 0x34, 0x64, 0x00, 0x56, 0xae, 0x4e, 0x7f, 0x00,
- 0x5b, 0xb3, 0x4e, 0x8f, 0x00, 0x61, 0x68, 0x35,
- 0x6c, 0x00, 0x61, 0xf2, 0x52, 0x50, 0x00, 0x66,
- 0x5f, 0x37, 0x39, 0x00, 0x67, 0x17, 0x37, 0x12,
- 0x00, 0x69, 0x82, 0x35, 0x70, 0x00, 0x75, 0x11,
- 0x4f, 0x3c, 0x00, 0x83, 0xdf, 0x4e, 0xe9, 0x00,
- 0x90, 0x77, 0x4f, 0x08, 0x00, 0x90, 0x89, 0x37,
- 0xa2, 0x00, 0x90, 0x8a, 0x37, 0x9d, 0x00, 0x97,
- 0xff, 0x4f, 0x15, 0x00, 0x99, 0x0c, 0x35, 0x52,
- 0x00, 0x99, 0x57, 0x4f, 0x19, 0x00, 0x00, 0x00,
- 0x06, 0x00, 0x51, 0xde, 0x21, 0x5e, 0x00, 0x53,
- 0xa9, 0x35, 0x4f, 0x00, 0x61, 0x68, 0x35, 0x6d,
- 0x00, 0x90, 0x89, 0x37, 0xa3, 0x00, 0x90, 0x8a,
- 0x37, 0x9e, 0x00, 0x97, 0xff, 0x4f, 0x16, 0x00,
- 0x00, 0x00, 0x04, 0x00, 0x53, 0xa9, 0x4f, 0x2f,
- 0x00, 0x61, 0x68, 0x35, 0x6e, 0x00, 0x90, 0x89,
- 0x37, 0xa4, 0x00, 0x90, 0x8a, 0x37, 0x9f, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x90, 0x89, 0x37, 0xa5,
- 0x00, 0x90, 0x8a, 0x37, 0xa0, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x90, 0x89, 0x37, 0xa6, 0x00, 0x90,
- 0x8a, 0x4f, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x90, 0x89, 0x37, 0xa7, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x90, 0x89, 0x37, 0xa8, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x90, 0x89, 0x37, 0xa9, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x90, 0x89, 0x37, 0xaa, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x90, 0x89, 0x37, 0xab,
+ 0x27, 0x02, 0xe6, 0xea, 0x37, 0x92, 0x03, 0x13,
+ 0x50, 0x4a, 0xba, 0x00, 0x00, 0x04, 0xb7, 0x00,
+ 0x34, 0x02, 0x35, 0x81, 0x00, 0x4e, 0x08, 0x34,
+ 0x97, 0x00, 0x4e, 0x0e, 0x4e, 0x69, 0x00, 0x4e,
+ 0x19, 0x36, 0xb9, 0x00, 0x4e, 0x26, 0x4e, 0x6a,
+ 0x00, 0x4e, 0x30, 0x3c, 0x1a, 0x00, 0x4e, 0x39,
+ 0x36, 0x5a, 0x00, 0x4e, 0x3b, 0x35, 0xf4, 0x00,
+ 0x4e, 0x73, 0x36, 0x90, 0x00, 0x4e, 0xa1, 0x36,
+ 0xcf, 0x00, 0x4e, 0xa4, 0x34, 0x7f, 0x00, 0x4e,
+ 0xca, 0x35, 0xd4, 0x00, 0x4f, 0x34, 0x36, 0xa0,
+ 0x00, 0x4f, 0x4f, 0x35, 0xfc, 0x00, 0x4f, 0x60,
+ 0x3c, 0x1c, 0x00, 0x4f, 0x73, 0x4e, 0x6c, 0x00,
+ 0x4f, 0x75, 0x34, 0x47, 0x00, 0x4f, 0x7f, 0x34,
+ 0x8a, 0x00, 0x4f, 0xae, 0x34, 0x46, 0x00, 0x4f,
+ 0xb5, 0x36, 0x1b, 0x00, 0x4f, 0xbf, 0x34, 0xc2,
+ 0x00, 0x50, 0x24, 0x36, 0x5f, 0x00, 0x50, 0x26,
+ 0x1d, 0xfa, 0x00, 0x50, 0x49, 0x34, 0x61, 0x00,
+ 0x50, 0x4f, 0x36, 0xbe, 0x00, 0x50, 0x56, 0x4e,
+ 0x6d, 0x00, 0x50, 0x65, 0x34, 0x7b, 0x00, 0x50,
+ 0x85, 0x34, 0xd0, 0x00, 0x50, 0x91, 0x34, 0x79,
+ 0x00, 0x50, 0xc5, 0x1d, 0xee, 0x00, 0x50, 0xca,
+ 0x1f, 0x2e, 0x00, 0x50, 0xcf, 0x34, 0xa2, 0x00,
+ 0x50, 0xe7, 0x34, 0x30, 0x00, 0x50, 0xed, 0x4e,
+ 0x6e, 0x00, 0x50, 0xf2, 0x52, 0xac, 0x00, 0x51,
+ 0x1a, 0x37, 0x16, 0x00, 0x51, 0x32, 0x1e, 0x76,
+ 0x00, 0x51, 0x46, 0x34, 0xa5, 0x00, 0x51, 0x4d,
+ 0x34, 0x4d, 0x00, 0x51, 0x4e, 0x36, 0x7d, 0x00,
+ 0x51, 0x54, 0x10, 0x74, 0x00, 0x51, 0x68, 0x36,
+ 0x42, 0x00, 0x51, 0x6b, 0x4e, 0x6f, 0x00, 0x51,
+ 0x6c, 0x34, 0x80, 0x00, 0x51, 0x77, 0x35, 0xa5,
+ 0x00, 0x51, 0x7c, 0x35, 0xb4, 0x00, 0x51, 0x89,
+ 0x1e, 0x87, 0x00, 0x51, 0x8d, 0x08, 0x36, 0x00,
+ 0x51, 0x92, 0x36, 0xd6, 0x00, 0x51, 0x93, 0x34,
+ 0xd1, 0x00, 0x51, 0x95, 0x10, 0x82, 0x00, 0x51,
+ 0xa4, 0x1e, 0x89, 0x00, 0x51, 0xac, 0x0c, 0x59,
+ 0x00, 0x51, 0xb4, 0x34, 0x5c, 0x00, 0x51, 0xcb,
+ 0x1e, 0x3e, 0x00, 0x51, 0xdb, 0x34, 0xd2, 0x00,
+ 0x51, 0xde, 0x4f, 0x53, 0x00, 0x51, 0xe1, 0x36,
+ 0xd9, 0x00, 0x51, 0xfd, 0x4e, 0x72, 0x00, 0x52,
+ 0x03, 0x36, 0x22, 0x00, 0x52, 0x06, 0x34, 0xbb,
+ 0x00, 0x52, 0x24, 0x36, 0xa1, 0x00, 0x52, 0x38,
+ 0x35, 0xb5, 0x00, 0x52, 0x4a, 0x35, 0xdd, 0x00,
+ 0x52, 0x4d, 0x36, 0x41, 0x00, 0x52, 0x64, 0x4e,
+ 0x74, 0x00, 0x52, 0x71, 0x4e, 0x75, 0x00, 0x52,
+ 0x72, 0x05, 0xc2, 0x00, 0x52, 0x75, 0x1e, 0x2b,
+ 0x00, 0x52, 0x8d, 0x37, 0x1a, 0x00, 0x52, 0xc7,
+ 0x36, 0xf6, 0x00, 0x52, 0xc9, 0x0e, 0x29, 0x00,
+ 0x52, 0xd7, 0x37, 0x1b, 0x00, 0x52, 0xdd, 0x36,
+ 0x05, 0x00, 0x52, 0xe2, 0x36, 0x2a, 0x00, 0x52,
+ 0xe4, 0x34, 0x1a, 0x00, 0x52, 0xfa, 0x09, 0x07,
+ 0x00, 0x53, 0x00, 0x37, 0xcf, 0x00, 0x53, 0x05,
+ 0x36, 0xc3, 0x00, 0x53, 0x07, 0x20, 0xd4, 0x00,
+ 0x53, 0x15, 0x1f, 0x2f, 0x00, 0x53, 0x16, 0x35,
+ 0x61, 0x00, 0x53, 0x39, 0x36, 0xaa, 0x00, 0x53,
+ 0x3f, 0x4e, 0x77, 0x00, 0x53, 0x40, 0x34, 0xd4,
+ 0x00, 0x53, 0x4a, 0x36, 0xa2, 0x00, 0x53, 0x51,
+ 0x0d, 0x70, 0x00, 0x53, 0x5a, 0x36, 0x98, 0x00,
+ 0x53, 0x65, 0x52, 0xf3, 0x00, 0x53, 0x71, 0x35,
+ 0x80, 0x00, 0x53, 0x78, 0x35, 0x5f, 0x00, 0x53,
+ 0x7f, 0x06, 0xa2, 0x00, 0x53, 0xa9, 0x1d, 0xd8,
+ 0x00, 0x53, 0xc9, 0x4f, 0x39, 0x00, 0x53, 0xca,
+ 0x35, 0x8e, 0x00, 0x53, 0xce, 0x34, 0x8f, 0x00,
+ 0x53, 0xd7, 0x35, 0xf5, 0x00, 0x53, 0xdb, 0x1f,
+ 0x2a, 0x00, 0x53, 0xdf, 0x37, 0x1f, 0x00, 0x53,
+ 0xe0, 0x53, 0x00, 0x00, 0x53, 0xf1, 0x1e, 0x0c,
+ 0x00, 0x53, 0xf2, 0x34, 0x8b, 0x00, 0x54, 0x0f,
+ 0x34, 0xc9, 0x00, 0x54, 0x38, 0x35, 0x8f, 0x00,
+ 0x54, 0x40, 0x4e, 0x79, 0x00, 0x54, 0x48, 0x36,
+ 0x76, 0x00, 0x54, 0x68, 0x09, 0x2a, 0x00, 0x54,
+ 0xac, 0x4f, 0x35, 0x00, 0x54, 0xb2, 0x35, 0xdc,
+ 0x00, 0x54, 0xe8, 0x1e, 0x17, 0x00, 0x55, 0x10,
+ 0x36, 0x83, 0x00, 0x55, 0x33, 0x1e, 0x8b, 0x00,
+ 0x55, 0x39, 0x1e, 0x8a, 0x00, 0x55, 0x44, 0x1e,
+ 0x32, 0x00, 0x55, 0x46, 0x36, 0x06, 0x00, 0x55,
+ 0x53, 0x35, 0xaa, 0x00, 0x55, 0x61, 0x38, 0x39,
+ 0x00, 0x55, 0x84, 0x4e, 0x5e, 0x00, 0x55, 0x9c,
+ 0x4e, 0x7b, 0x00, 0x55, 0x9d, 0x1d, 0xe3, 0x00,
+ 0x55, 0xa9, 0x1f, 0x30, 0x00, 0x55, 0xab, 0x35,
+ 0x8b, 0x00, 0x55, 0xb0, 0x1d, 0xf0, 0x00, 0x55,
+ 0xe4, 0x1e, 0x8c, 0x00, 0x56, 0x05, 0x53, 0x2d,
+ 0x00, 0x56, 0x06, 0x0b, 0x70, 0x00, 0x56, 0x09,
+ 0x4e, 0x7d, 0x00, 0x56, 0x32, 0x1e, 0x8d, 0x00,
+ 0x56, 0x42, 0x1d, 0xda, 0x00, 0x56, 0x4c, 0x1e,
+ 0x29, 0x00, 0x56, 0x68, 0x34, 0x15, 0x00, 0x56,
+ 0x74, 0x34, 0xbc, 0x00, 0x56, 0x78, 0x1e, 0x52,
+ 0x00, 0x56, 0xa5, 0x1e, 0x8e, 0x00, 0x56, 0xae,
+ 0x1f, 0x31, 0x00, 0x56, 0xc0, 0x37, 0x24, 0x00,
+ 0x56, 0xc1, 0x34, 0xd7, 0x00, 0x56, 0xce, 0x4e,
+ 0x82, 0x00, 0x56, 0xee, 0x4e, 0x83, 0x00, 0x57,
+ 0x0d, 0x34, 0xd8, 0x00, 0x57, 0x47, 0x34, 0x78,
+ 0x00, 0x57, 0x6a, 0x36, 0x74, 0x00, 0x57, 0xce,
+ 0x09, 0xd3, 0x00, 0x57, 0xd6, 0x4e, 0x84, 0x00,
+ 0x57, 0xf4, 0x34, 0x98, 0x00, 0x58, 0x0b, 0x1e,
+ 0x8f, 0x00, 0x58, 0x19, 0x1f, 0x32, 0x00, 0x58,
+ 0x35, 0x1e, 0x49, 0x00, 0x58, 0x3d, 0x4e, 0x85,
+ 0x00, 0x58, 0x40, 0x34, 0x48, 0x00, 0x58, 0x58,
+ 0x1e, 0x4d, 0x00, 0x58, 0x59, 0x4e, 0x86, 0x00,
+ 0x58, 0x5a, 0x1e, 0x42, 0x00, 0x58, 0x9c, 0x36,
+ 0x71, 0x00, 0x58, 0xa8, 0x0e, 0x7d, 0x00, 0x58,
+ 0xab, 0x34, 0xd9, 0x00, 0x59, 0x06, 0x53, 0x7b,
+ 0x00, 0x59, 0x1b, 0x1f, 0x33, 0x00, 0x59, 0x27,
+ 0x36, 0x55, 0x00, 0x59, 0x4f, 0x4e, 0x87, 0x00,
+ 0x59, 0x51, 0x35, 0xab, 0x00, 0x59, 0x53, 0x37,
+ 0xd1, 0x00, 0x59, 0x60, 0x4e, 0x89, 0x00, 0x59,
+ 0x62, 0x4e, 0x8a, 0x00, 0x59, 0x73, 0x36, 0x04,
+ 0x00, 0x59, 0x84, 0x36, 0xe7, 0x00, 0x59, 0xa5,
+ 0x36, 0x4f, 0x00, 0x59, 0xc9, 0x34, 0x8c, 0x00,
+ 0x59, 0xda, 0x34, 0xda, 0x00, 0x59, 0xec, 0x36,
+ 0xae, 0x00, 0x59, 0xff, 0x35, 0xe0, 0x00, 0x5a,
+ 0x1c, 0x37, 0x26, 0x00, 0x5a, 0x29, 0x1e, 0x6f,
+ 0x00, 0x5a, 0x36, 0x34, 0xdb, 0x00, 0x5a, 0x66,
+ 0x36, 0xb2, 0x00, 0x5a, 0x9b, 0x1e, 0x68, 0x00,
+ 0x5a, 0xbe, 0x1e, 0x90, 0x00, 0x5a, 0xc2, 0x37,
+ 0x27, 0x00, 0x5a, 0xcc, 0x1d, 0xfb, 0x00, 0x5a,
+ 0xda, 0x4e, 0x8b, 0x00, 0x5b, 0x5a, 0x4e, 0x8c,
+ 0x00, 0x5b, 0x73, 0x4e, 0x8d, 0x00, 0x5b, 0x7c,
+ 0x4e, 0x8e, 0x00, 0x5b, 0xb3, 0x34, 0x6d, 0x00,
+ 0x5b, 0xb5, 0x36, 0x07, 0x00, 0x5b, 0xc3, 0x37,
+ 0x29, 0x00, 0x5b, 0xd2, 0x35, 0x78, 0x00, 0x5b,
+ 0xdb, 0x20, 0xf4, 0x00, 0x5b, 0xe7, 0x0c, 0xe1,
+ 0x00, 0x5b, 0xe8, 0x37, 0x42, 0x00, 0x5c, 0x06,
+ 0x09, 0x95, 0x00, 0x5c, 0x0a, 0x36, 0x4d, 0x00,
+ 0x5c, 0x0b, 0x36, 0x23, 0x00, 0x5c, 0x0e, 0x36,
+ 0x8a, 0x00, 0x5c, 0x0f, 0x36, 0x09, 0x00, 0x5c,
+ 0x28, 0x1f, 0x34, 0x00, 0x5c, 0x51, 0x1d, 0xf2,
+ 0x00, 0x5c, 0x60, 0x1e, 0x4a, 0x00, 0x5c, 0x64,
+ 0x34, 0x31, 0x00, 0x5c, 0x6e, 0x12, 0x32, 0x00,
+ 0x5d, 0x29, 0x36, 0xc4, 0x00, 0x5d, 0x4e, 0x34,
+ 0xdd, 0x00, 0x5d, 0x87, 0x34, 0xde, 0x00, 0x5d,
+ 0xb2, 0x3c, 0x2d, 0x00, 0x5d, 0xc9, 0x34, 0xdf,
+ 0x00, 0x5d, 0xcc, 0x34, 0x73, 0x00, 0x5d, 0xd3,
+ 0x34, 0xe0, 0x00, 0x5d, 0xe1, 0x35, 0xff, 0x00,
+ 0x5d, 0xe5, 0x35, 0xc3, 0x00, 0x5d, 0xe8, 0x35,
+ 0x92, 0x00, 0x5d, 0xf7, 0x1d, 0xff, 0x00, 0x5d,
+ 0xfd, 0x0b, 0x65, 0x00, 0x5e, 0x06, 0x36, 0xa3,
+ 0x00, 0x5e, 0x1d, 0x36, 0x77, 0x00, 0x5e, 0x30,
+ 0x34, 0x75, 0x00, 0x5e, 0x3d, 0x36, 0xd0, 0x00,
+ 0x5e, 0x43, 0x4e, 0x91, 0x00, 0x5e, 0x54, 0x37,
+ 0x2d, 0x00, 0x5e, 0x63, 0x36, 0xba, 0x00, 0x5e,
+ 0x64, 0x1e, 0x93, 0x00, 0x5e, 0x73, 0x36, 0xbb,
+ 0x00, 0x5e, 0x7e, 0x35, 0x84, 0x00, 0x5e, 0x96,
+ 0x1e, 0x70, 0x00, 0x5e, 0xa7, 0x4e, 0x92, 0x00,
+ 0x5e, 0xad, 0x34, 0xa9, 0x00, 0x5e, 0xc9, 0x0f,
+ 0xbf, 0x00, 0x5e, 0xca, 0x4f, 0x4f, 0x00, 0x5e,
+ 0xcb, 0x38, 0xae, 0x00, 0x5e, 0xcf, 0x1f, 0x36,
+ 0x00, 0x5e, 0xd0, 0x1f, 0x35, 0x00, 0x5e, 0xdf,
+ 0x1e, 0x6a, 0x00, 0x5e, 0xe0, 0x1e, 0x18, 0x00,
+ 0x5e, 0xe3, 0x37, 0x2f, 0x00, 0x5e, 0xf6, 0x34,
+ 0x67, 0x00, 0x5e, 0xf7, 0x34, 0xaa, 0x00, 0x5e,
+ 0xfa, 0x34, 0x7c, 0x00, 0x5e, 0xfb, 0x35, 0x69,
+ 0x00, 0x5f, 0x0a, 0x36, 0xbc, 0x00, 0x5f, 0x2d,
+ 0x34, 0xe1, 0x00, 0x5f, 0x31, 0x35, 0xf3, 0x00,
+ 0x5f, 0x38, 0x4e, 0x94, 0x00, 0x5f, 0x45, 0x37,
+ 0xce, 0x00, 0x5f, 0x50, 0x3c, 0x1f, 0x00, 0x5f,
+ 0x62, 0x4e, 0x5f, 0x00, 0x5f, 0x69, 0x35, 0xd7,
+ 0x00, 0x5f, 0x6b, 0x36, 0x68, 0x00, 0x5f, 0x80,
+ 0x35, 0x5d, 0x00, 0x5f, 0x98, 0x34, 0xe2, 0x00,
+ 0x5f, 0xa1, 0x4e, 0x95, 0x00, 0x5f, 0xae, 0x36,
+ 0xa8, 0x00, 0x5f, 0xb5, 0x36, 0x69, 0x00, 0x5f,
+ 0xbd, 0x1d, 0xea, 0x00, 0x5f, 0xcd, 0x36, 0x91,
+ 0x00, 0x5f, 0xd8, 0x36, 0xd1, 0x00, 0x5f, 0xd9,
+ 0x36, 0xd2, 0x00, 0x5f, 0xdd, 0x4e, 0x96, 0x00,
+ 0x60, 0x25, 0x35, 0x90, 0x00, 0x60, 0x50, 0x35,
+ 0x99, 0x00, 0x60, 0x62, 0x1d, 0xe0, 0x00, 0x60,
+ 0x65, 0x34, 0xa4, 0x00, 0x60, 0x75, 0x35, 0xac,
+ 0x00, 0x60, 0x94, 0x05, 0x79, 0x00, 0x60, 0x97,
+ 0x1e, 0x94, 0x00, 0x60, 0x9e, 0x54, 0x36, 0x00,
+ 0x60, 0xa4, 0x3c, 0x20, 0x00, 0x60, 0xb2, 0x34,
+ 0xb3, 0x00, 0x60, 0xc5, 0x36, 0x12, 0x00, 0x60,
+ 0xd8, 0x34, 0xe3, 0x00, 0x61, 0x08, 0x1e, 0x7a,
+ 0x00, 0x61, 0x09, 0x36, 0xf3, 0x00, 0x61, 0x0f,
+ 0x35, 0x47, 0x00, 0x61, 0x3d, 0x34, 0xe4, 0x00,
+ 0x61, 0x48, 0x4e, 0x60, 0x00, 0x61, 0x4c, 0x35,
+ 0xc4, 0x00, 0x61, 0x4e, 0x34, 0x2c, 0x00, 0x61,
+ 0x62, 0x4e, 0x97, 0x00, 0x61, 0x67, 0x1d, 0xf5,
+ 0x00, 0x61, 0x68, 0x34, 0x10, 0x00, 0x61, 0x8e,
+ 0x0b, 0x00, 0x00, 0x61, 0x90, 0x37, 0x10, 0x00,
+ 0x61, 0xa4, 0x34, 0xbd, 0x00, 0x61, 0xb2, 0x35,
+ 0xb6, 0x00, 0x61, 0xf2, 0x34, 0x39, 0x00, 0x61,
+ 0xf8, 0x4e, 0x99, 0x00, 0x61, 0xfe, 0x34, 0xe5,
+ 0x00, 0x62, 0x10, 0x36, 0x2b, 0x00, 0x62, 0x3b,
+ 0x36, 0xeb, 0x00, 0x62, 0x3f, 0x36, 0xd3, 0x00,
+ 0x62, 0x40, 0x36, 0x02, 0x00, 0x62, 0x41, 0x1f,
+ 0x37, 0x00, 0x62, 0x47, 0x36, 0x3b, 0x00, 0x62,
+ 0x48, 0x1e, 0xc2, 0x00, 0x62, 0x49, 0x1e, 0x63,
+ 0x00, 0x62, 0x68, 0x34, 0xe6, 0x00, 0x62, 0x71,
+ 0x35, 0x45, 0x00, 0x62, 0xb1, 0x36, 0xc5, 0x00,
+ 0x62, 0xcc, 0x37, 0x32, 0x00, 0x62, 0xcf, 0x34,
+ 0xe7, 0x00, 0x62, 0xd0, 0x1d, 0xe1, 0x00, 0x62,
+ 0xd2, 0x35, 0x93, 0x00, 0x62, 0xd4, 0x13, 0x5d,
+ 0x00, 0x62, 0xf3, 0x1f, 0x21, 0x00, 0x62, 0xf7,
+ 0x34, 0x88, 0x00, 0x63, 0x3a, 0x4f, 0x3e, 0x00,
+ 0x63, 0x3d, 0x1e, 0x62, 0x00, 0x63, 0x4c, 0x34,
+ 0x5d, 0x00, 0x63, 0x57, 0x1e, 0x3f, 0x00, 0x63,
+ 0x67, 0x34, 0xc3, 0x00, 0x63, 0x68, 0x35, 0xec,
+ 0x00, 0x63, 0x69, 0x1e, 0x95, 0x00, 0x63, 0x6e,
+ 0x34, 0x9d, 0x00, 0x63, 0x72, 0x1d, 0xfc, 0x00,
+ 0x63, 0x83, 0x36, 0x43, 0x00, 0x63, 0x88, 0x35,
+ 0xf6, 0x00, 0x63, 0x92, 0x34, 0xaf, 0x00, 0x63,
+ 0xa1, 0x35, 0xd8, 0x00, 0x63, 0xa7, 0x35, 0xc6,
+ 0x00, 0x63, 0xc3, 0x1f, 0x27, 0x00, 0x63, 0xc6,
+ 0x37, 0x34, 0x00, 0x63, 0xf4, 0x35, 0x57, 0x00,
+ 0x64, 0x06, 0x1e, 0x96, 0x00, 0x64, 0x0f, 0x34,
+ 0xe9, 0x00, 0x64, 0x1c, 0x37, 0x33, 0x00, 0x64,
+ 0x28, 0x37, 0x35, 0x00, 0x64, 0x42, 0x34, 0x9e,
+ 0x00, 0x64, 0x69, 0x36, 0xd7, 0x00, 0x64, 0x6f,
+ 0x4f, 0x28, 0x00, 0x64, 0x7a, 0x1e, 0x21, 0x00,
+ 0x64, 0xb0, 0x1e, 0x24, 0x00, 0x64, 0xe2, 0x1e,
+ 0x45, 0x00, 0x64, 0xf2, 0x34, 0xea, 0x00, 0x64,
+ 0xf6, 0x4e, 0x9e, 0x00, 0x65, 0x1d, 0x34, 0xe8,
+ 0x00, 0x65, 0x4f, 0x0d, 0xc4, 0x00, 0x65, 0x5d,
+ 0x34, 0xeb, 0x00, 0x65, 0x5e, 0x4e, 0xa1, 0x00,
+ 0x65, 0x62, 0x34, 0x71, 0x00, 0x65, 0x77, 0x36,
+ 0xb3, 0x00, 0x65, 0x83, 0x1e, 0x98, 0x00, 0x65,
+ 0x87, 0x4e, 0xa3, 0x00, 0x65, 0x89, 0x4e, 0xa4,
+ 0x00, 0x65, 0x8e, 0x4e, 0xa6, 0x00, 0x65, 0x90,
+ 0x34, 0xb5, 0x00, 0x65, 0x9c, 0x35, 0xed, 0x00,
+ 0x65, 0xa7, 0x4f, 0x41, 0x00, 0x65, 0xbc, 0x35,
+ 0x5c, 0x00, 0x65, 0xc5, 0x37, 0x08, 0x00, 0x65,
+ 0xdf, 0x54, 0xbe, 0x00, 0x65, 0xe1, 0x4e, 0xa9,
+ 0x00, 0x65, 0xe2, 0x06, 0x37, 0x00, 0x66, 0x0e,
+ 0x36, 0xe4, 0x00, 0x66, 0x1e, 0x21, 0x1c, 0x00,
+ 0x66, 0x5f, 0x34, 0xec, 0x00, 0x66, 0x66, 0x1d,
+ 0xe2, 0x00, 0x66, 0x67, 0x4e, 0xaa, 0x00, 0x66,
+ 0x69, 0x36, 0xa5, 0x00, 0x66, 0x6e, 0x4e, 0xab,
+ 0x00, 0x66, 0x74, 0x0a, 0x56, 0x00, 0x66, 0x77,
+ 0x39, 0x11, 0x00, 0x66, 0x81, 0x35, 0xa0, 0x00,
+ 0x66, 0x91, 0x34, 0x28, 0x00, 0x66, 0x96, 0x36,
+ 0x5e, 0x00, 0x66, 0x97, 0x35, 0x46, 0x00, 0x66,
+ 0xb5, 0x54, 0xda, 0x00, 0x66, 0xc1, 0x1f, 0x38,
+ 0x00, 0x66, 0xd9, 0x1e, 0x13, 0x00, 0x66, 0xdc,
+ 0x36, 0xfd, 0x00, 0x66, 0xf4, 0x34, 0x81, 0x00,
+ 0x66, 0xf5, 0x37, 0x3b, 0x00, 0x66, 0xf8, 0x36,
+ 0x03, 0x00, 0x66, 0xfb, 0x37, 0xcd, 0x00, 0x66,
+ 0xfc, 0x37, 0x20, 0x00, 0x67, 0x00, 0x4e, 0xaf,
+ 0x00, 0x67, 0x08, 0x35, 0xb2, 0x00, 0x67, 0x09,
+ 0x36, 0xf7, 0x00, 0x67, 0x0b, 0x36, 0xc6, 0x00,
+ 0x67, 0x0d, 0x36, 0xb7, 0x00, 0x67, 0x15, 0x36,
+ 0x6f, 0x00, 0x67, 0x17, 0x0f, 0xd5, 0x00, 0x67,
+ 0x1b, 0x36, 0xd4, 0x00, 0x67, 0x1d, 0x36, 0x6b,
+ 0x00, 0x67, 0x1f, 0x35, 0x86, 0x00, 0x67, 0x53,
+ 0x1e, 0x0f, 0x00, 0x67, 0x56, 0x4f, 0x3a, 0x00,
+ 0x67, 0x5e, 0x37, 0x3c, 0x00, 0x67, 0x61, 0x4e,
+ 0xb0, 0x00, 0x67, 0x7e, 0x34, 0x95, 0x00, 0x67,
+ 0xa6, 0x1e, 0x99, 0x00, 0x67, 0xa9, 0x34, 0xed,
+ 0x00, 0x67, 0xc4, 0x4e, 0xb1, 0x00, 0x67, 0xca,
+ 0x1e, 0x65, 0x00, 0x67, 0xd4, 0x34, 0x91, 0x00,
+ 0x67, 0xe7, 0x34, 0xee, 0x00, 0x67, 0xf1, 0x36,
+ 0x65, 0x00, 0x68, 0x01, 0x21, 0x2e, 0x00, 0x68,
+ 0x02, 0x4e, 0xb2, 0x00, 0x68, 0x13, 0x1e, 0x25,
+ 0x00, 0x68, 0x1f, 0x4e, 0x61, 0x00, 0x68, 0x21,
+ 0x34, 0x82, 0x00, 0x68, 0x43, 0x34, 0xac, 0x00,
+ 0x68, 0x52, 0x21, 0x2c, 0x00, 0x68, 0x5d, 0x34,
+ 0xc5, 0x00, 0x68, 0x7a, 0x36, 0xf0, 0x00, 0x68,
+ 0x81, 0x37, 0x09, 0x00, 0x68, 0x85, 0x0d, 0x15,
+ 0x00, 0x68, 0x8d, 0x37, 0x3e, 0x00, 0x68, 0x97,
+ 0x4f, 0x37, 0x00, 0x68, 0x9b, 0x1e, 0x9b, 0x00,
+ 0x68, 0x9d, 0x37, 0x3d, 0x00, 0x68, 0xa2, 0x1e,
+ 0x19, 0x00, 0x68, 0xc8, 0x37, 0xcc, 0x00, 0x68,
+ 0xda, 0x1e, 0x38, 0x00, 0x69, 0x0d, 0x34, 0x99,
+ 0x00, 0x69, 0x30, 0x34, 0xf0, 0x00, 0x69, 0x3d,
+ 0x4e, 0xb3, 0x00, 0x69, 0x5e, 0x4e, 0xb4, 0x00,
+ 0x69, 0x62, 0x1e, 0x58, 0x00, 0x69, 0x6b, 0x34,
+ 0xef, 0x00, 0x69, 0x6f, 0x34, 0x94, 0x00, 0x69,
+ 0x82, 0x34, 0x5b, 0x00, 0x69, 0x8a, 0x1e, 0x06,
+ 0x00, 0x69, 0x94, 0x1e, 0x84, 0x00, 0x69, 0xa7,
+ 0x34, 0xf1, 0x00, 0x69, 0xbb, 0x37, 0x43, 0x00,
+ 0x69, 0xc1, 0x35, 0x9a, 0x00, 0x69, 0xcb, 0x35,
+ 0xc7, 0x00, 0x69, 0xcc, 0x1e, 0x40, 0x00, 0x69,
+ 0xd9, 0x36, 0xdd, 0x00, 0x69, 0xea, 0x35, 0x6f,
+ 0x00, 0x69, 0xfe, 0x55, 0x1f, 0x00, 0x6a, 0x0b,
+ 0x1e, 0x64, 0x00, 0x6a, 0x3d, 0x1e, 0x3a, 0x00,
+ 0x6a, 0x44, 0x34, 0xf2, 0x00, 0x6a, 0x55, 0x55,
+ 0x25, 0x00, 0x6a, 0x5f, 0x35, 0x87, 0x00, 0x6a,
+ 0x73, 0x37, 0xd4, 0x00, 0x6a, 0x8e, 0x34, 0x7e,
+ 0x00, 0x6a, 0x90, 0x34, 0xf3, 0x00, 0x6a, 0x9c,
+ 0x4e, 0xb6, 0x00, 0x6a, 0xdb, 0x06, 0xf3, 0x00,
+ 0x6b, 0x04, 0x0f, 0x5d, 0x00, 0x6b, 0x1d, 0x1d,
+ 0xd7, 0x00, 0x6b, 0x21, 0x35, 0xe7, 0x00, 0x6b,
+ 0x24, 0x3c, 0x22, 0x00, 0x6b, 0x4e, 0x36, 0x5b,
+ 0x00, 0x6b, 0x96, 0x36, 0x16, 0x00, 0x6b, 0xba,
+ 0x08, 0x74, 0x00, 0x6b, 0xbb, 0x34, 0x70, 0x00,
+ 0x6c, 0x08, 0x1f, 0x39, 0x00, 0x6c, 0x13, 0x34,
+ 0xf5, 0x00, 0x6c, 0x38, 0x4e, 0xba, 0x00, 0x6c,
+ 0x3a, 0x39, 0x62, 0x00, 0x6c, 0x72, 0x1f, 0x1e,
+ 0x00, 0x6c, 0xaa, 0x37, 0x48, 0x00, 0x6c, 0xbf,
+ 0x05, 0x0a, 0x00, 0x6c, 0xe1, 0x1e, 0x71, 0x00,
+ 0x6c, 0xe8, 0x36, 0x66, 0x00, 0x6d, 0x3e, 0x34,
+ 0xae, 0x00, 0x6d, 0x69, 0x35, 0xc8, 0x00, 0x6d,
+ 0x6e, 0x36, 0xb4, 0x00, 0x6d, 0x77, 0x05, 0x82,
+ 0x00, 0x6d, 0x78, 0x36, 0x1d, 0x00, 0x6d, 0x88,
+ 0x36, 0x0c, 0x00, 0x6d, 0xe4, 0x4e, 0xbd, 0x00,
+ 0x6d, 0xeb, 0x1d, 0xd5, 0x00, 0x6d, 0xfb, 0x36,
+ 0x7c, 0x00, 0x6e, 0x08, 0x4e, 0xbf, 0x00, 0x6e,
+ 0x1a, 0x09, 0x77, 0x00, 0x6e, 0x23, 0x1f, 0x3a,
+ 0x00, 0x6e, 0x2f, 0x35, 0xc9, 0x00, 0x6e, 0x6e,
+ 0x1e, 0x9d, 0x00, 0x6e, 0x72, 0x4e, 0xc0, 0x00,
+ 0x6e, 0x7e, 0x34, 0xcf, 0x00, 0x6e, 0x9d, 0x1e,
+ 0x01, 0x00, 0x6e, 0xa2, 0x1d, 0xd3, 0x00, 0x6e,
+ 0xba, 0x1e, 0x46, 0x00, 0x6e, 0xcb, 0x35, 0xe9,
+ 0x00, 0x6e, 0xd5, 0x4e, 0xc2, 0x00, 0x6e, 0xdb,
+ 0x4e, 0xc3, 0x00, 0x6e, 0xec, 0x1f, 0x3b, 0x00,
+ 0x6e, 0xfe, 0x34, 0xf8, 0x00, 0x6f, 0x11, 0x34,
+ 0xf7, 0x00, 0x6f, 0x22, 0x34, 0x14, 0x00, 0x6f,
+ 0x23, 0x0f, 0xc2, 0x00, 0x6f, 0x3e, 0x34, 0xf9,
+ 0x00, 0x6f, 0x51, 0x36, 0x9e, 0x00, 0x6f, 0x54,
+ 0x35, 0xb0, 0x00, 0x6f, 0x5b, 0x4e, 0xc4, 0x00,
+ 0x6f, 0x64, 0x4e, 0xc6, 0x00, 0x6f, 0x6e, 0x0b,
+ 0xc8, 0x00, 0x6f, 0x74, 0x4e, 0xc7, 0x00, 0x6f,
+ 0x98, 0x37, 0x47, 0x00, 0x6f, 0xef, 0x1e, 0x33,
+ 0x00, 0x6f, 0xf9, 0x39, 0x95, 0x00, 0x70, 0x15,
+ 0x1e, 0x6b, 0x00, 0x70, 0x1b, 0x37, 0x4a, 0x00,
+ 0x70, 0x1e, 0x1e, 0x51, 0x00, 0x70, 0x26, 0x1e,
+ 0x3d, 0x00, 0x70, 0x27, 0x36, 0x57, 0x00, 0x70,
+ 0x4a, 0x39, 0x98, 0x00, 0x70, 0x58, 0x1e, 0x57,
+ 0x00, 0x70, 0x70, 0x35, 0x6a, 0x00, 0x70, 0x78,
+ 0x4f, 0x2e, 0x00, 0x70, 0x7c, 0x1e, 0x10, 0x00,
+ 0x70, 0xad, 0x36, 0x5c, 0x00, 0x71, 0x49, 0x0f,
+ 0xc3, 0x00, 0x71, 0x4e, 0x1e, 0x26, 0x00, 0x71,
+ 0x52, 0x55, 0xad, 0x00, 0x71, 0x59, 0x35, 0x59,
+ 0x00, 0x71, 0x62, 0x37, 0x4b, 0x00, 0x71, 0x6e,
+ 0x08, 0xfd, 0x00, 0x71, 0x7d, 0x1e, 0x27, 0x00,
+ 0x71, 0x94, 0x1e, 0x7d, 0x00, 0x71, 0xb3, 0x39,
+ 0xae, 0x00, 0x71, 0xd0, 0x37, 0x0a, 0x00, 0x71,
+ 0xff, 0x34, 0xfa, 0x00, 0x72, 0x28, 0x15, 0xdf,
+ 0x00, 0x72, 0x2b, 0x3c, 0x26, 0x00, 0x72, 0x35,
+ 0x09, 0x0b, 0x00, 0x72, 0x36, 0x34, 0xb9, 0x00,
+ 0x72, 0x3a, 0x4f, 0x46, 0x00, 0x72, 0x3b, 0x37,
+ 0x4c, 0x00, 0x72, 0x3e, 0x4e, 0xc9, 0x00, 0x72,
+ 0x4c, 0x1e, 0x5b, 0x00, 0x72, 0x59, 0x1f, 0x1d,
+ 0x00, 0x72, 0xe1, 0x4f, 0x36, 0x00, 0x73, 0x1c,
+ 0x37, 0x4e, 0x00, 0x73, 0x2a, 0x0b, 0xb4, 0x00,
+ 0x73, 0x36, 0x36, 0xf8, 0x00, 0x73, 0x37, 0x1e,
+ 0x7c, 0x00, 0x73, 0x87, 0x37, 0x05, 0x00, 0x73,
+ 0x8b, 0x35, 0xa1, 0x00, 0x73, 0xca, 0x1e, 0x0b,
+ 0x00, 0x73, 0xce, 0x1e, 0xa0, 0x00, 0x73, 0xe5,
+ 0x34, 0xfb, 0x00, 0x73, 0xed, 0x34, 0xb1, 0x00,
+ 0x74, 0x22, 0x0b, 0x56, 0x00, 0x74, 0x32, 0x34,
+ 0xfc, 0x00, 0x74, 0x5f, 0x34, 0xfd, 0x00, 0x74,
+ 0x62, 0x21, 0x71, 0x00, 0x74, 0xb0, 0x35, 0x79,
+ 0x00, 0x74, 0xbd, 0x4e, 0xcd, 0x00, 0x74, 0xca,
+ 0x37, 0x4f, 0x00, 0x74, 0xd8, 0x55, 0xf6, 0x00,
+ 0x74, 0xdc, 0x35, 0x50, 0x00, 0x74, 0xe0, 0x34,
+ 0xfe, 0x00, 0x74, 0xef, 0x55, 0xfa, 0x00, 0x75,
+ 0x04, 0x1e, 0xa1, 0x00, 0x75, 0x0c, 0x34, 0xff,
+ 0x00, 0x75, 0x0d, 0x1e, 0xa2, 0x00, 0x75, 0x11,
+ 0x1e, 0x04, 0x00, 0x75, 0x15, 0x1e, 0xa3, 0x00,
+ 0x75, 0x26, 0x4f, 0x3b, 0x00, 0x75, 0x54, 0x36,
+ 0xa4, 0x00, 0x75, 0x5d, 0x4e, 0xce, 0x00, 0x75,
+ 0xbc, 0x4e, 0xcf, 0x00, 0x75, 0xc5, 0x36, 0xb1,
+ 0x00, 0x76, 0x08, 0x4e, 0xd1, 0x00, 0x76, 0x26,
+ 0x1e, 0x2d, 0x00, 0x76, 0x52, 0x1e, 0x7b, 0x00,
+ 0x76, 0x64, 0x4e, 0xd2, 0x00, 0x76, 0x69, 0x4e,
+ 0xd3, 0x00, 0x76, 0x72, 0x35, 0x00, 0x00, 0x76,
+ 0x84, 0x36, 0x79, 0x00, 0x76, 0x93, 0x1e, 0xa4,
+ 0x00, 0x76, 0xc6, 0x34, 0xc4, 0x00, 0x76, 0xca,
+ 0x21, 0x7b, 0x00, 0x76, 0xd4, 0x56, 0x1d, 0x00,
+ 0x76, 0xdb, 0x36, 0x2c, 0x00, 0x76, 0xdf, 0x36,
+ 0xe5, 0x00, 0x76, 0xf2, 0x36, 0xe9, 0x00, 0x76,
+ 0xf4, 0x36, 0x6e, 0x00, 0x77, 0x1e, 0x16, 0xb8,
+ 0x00, 0x77, 0x1f, 0x36, 0x1e, 0x00, 0x77, 0x37,
+ 0x4e, 0xd5, 0x00, 0x77, 0x3a, 0x34, 0xa6, 0x00,
+ 0x77, 0x7e, 0x4e, 0xd6, 0x00, 0x77, 0x8d, 0x56,
+ 0x2e, 0x00, 0x77, 0xa2, 0x56, 0x2f, 0x00, 0x77,
+ 0xa5, 0x1e, 0x6e, 0x00, 0x77, 0xac, 0x34, 0x92,
+ 0x00, 0x77, 0xe9, 0x35, 0xa4, 0x00, 0x78, 0x32,
+ 0x36, 0xc7, 0x00, 0x78, 0x3a, 0x36, 0x7f, 0x00,
+ 0x78, 0x5d, 0x36, 0x0d, 0x00, 0x78, 0x6c, 0x34,
+ 0x83, 0x00, 0x78, 0x7c, 0x1e, 0xa5, 0x00, 0x78,
+ 0x91, 0x0d, 0x7e, 0x00, 0x78, 0xd4, 0x35, 0x02,
+ 0x00, 0x78, 0xe8, 0x36, 0xda, 0x00, 0x78, 0xef,
+ 0x35, 0x4b, 0x00, 0x79, 0x2a, 0x35, 0x01, 0x00,
+ 0x79, 0x34, 0x3a, 0x38, 0x00, 0x79, 0x3a, 0x08,
+ 0xd4, 0x00, 0x79, 0x3c, 0x21, 0x83, 0x00, 0x79,
+ 0x3e, 0x34, 0x24, 0x00, 0x79, 0x40, 0x37, 0x57,
+ 0x00, 0x79, 0x41, 0x1d, 0xf4, 0x00, 0x79, 0x47,
+ 0x1d, 0xeb, 0x00, 0x79, 0x48, 0x06, 0x41, 0x00,
+ 0x79, 0x49, 0x34, 0x21, 0x00, 0x79, 0x50, 0x0f,
+ 0x1e, 0x00, 0x79, 0x53, 0x37, 0x58, 0x00, 0x79,
+ 0x56, 0x34, 0x2f, 0x00, 0x79, 0x5d, 0x09, 0x55,
+ 0x00, 0x79, 0x5e, 0x0a, 0x06, 0x00, 0x79, 0x62,
+ 0x1f, 0x29, 0x00, 0x79, 0x65, 0x09, 0xb5, 0x00,
+ 0x79, 0x8d, 0x05, 0x52, 0x00, 0x79, 0x8e, 0x34,
+ 0x3b, 0x00, 0x79, 0x8f, 0x21, 0x87, 0x00, 0x79,
+ 0xa7, 0x4e, 0xd7, 0x00, 0x79, 0xae, 0x37, 0x5b,
+ 0x00, 0x79, 0xb0, 0x1e, 0x59, 0x00, 0x79, 0xb1,
+ 0x4e, 0xd8, 0x00, 0x79, 0xba, 0x35, 0x03, 0x00,
+ 0x79, 0xe4, 0x1e, 0x5d, 0x00, 0x7a, 0x0b, 0x36,
+ 0x78, 0x00, 0x7a, 0x17, 0x1e, 0x66, 0x00, 0x7a,
+ 0x19, 0x35, 0x04, 0x00, 0x7a, 0x31, 0x1e, 0xa6,
+ 0x00, 0x7a, 0x40, 0x08, 0x04, 0x00, 0x7a, 0x60,
+ 0x3a, 0x4e, 0x00, 0x7a, 0x74, 0x34, 0x7a, 0x00,
+ 0x7a, 0x7a, 0x35, 0xa7, 0x00, 0x7a, 0x7f, 0x1f,
+ 0x25, 0x00, 0x7a, 0x81, 0x34, 0x3d, 0x00, 0x7a,
+ 0x95, 0x35, 0x05, 0x00, 0x7a, 0x97, 0x1f, 0x3c,
+ 0x00, 0x7a, 0xae, 0x34, 0x77, 0x00, 0x7a, 0xbe,
+ 0x4e, 0xd9, 0x00, 0x7a, 0xc6, 0x3c, 0x27, 0x00,
+ 0x7a, 0xc8, 0x4f, 0x3d, 0x00, 0x7b, 0x08, 0x1f,
+ 0x1f, 0x00, 0x7b, 0x51, 0x36, 0x63, 0x00, 0x7b,
+ 0x75, 0x4f, 0x2a, 0x00, 0x7b, 0x99, 0x1e, 0xa8,
+ 0x00, 0x7b, 0xad, 0x1f, 0x26, 0x00, 0x7b, 0xb8,
+ 0x1e, 0x5f, 0x00, 0x7b, 0xc0, 0x34, 0x2e, 0x00,
+ 0x7b, 0xc7, 0x1f, 0x2b, 0x00, 0x7b, 0xc9, 0x36,
+ 0x61, 0x00, 0x7b, 0xdd, 0x1f, 0x3d, 0x00, 0x7b,
+ 0xe0, 0x4e, 0xda, 0x00, 0x7c, 0x14, 0x37, 0x5f,
+ 0x00, 0x7c, 0x3e, 0x1f, 0x2d, 0x00, 0x7c, 0x3f,
+ 0x36, 0xc2, 0x00, 0x7c, 0x4d, 0x36, 0x36, 0x00,
+ 0x7c, 0x50, 0x37, 0x61, 0x00, 0x7c, 0x58, 0x37,
+ 0x62, 0x00, 0x7c, 0x69, 0x56, 0xaa, 0x00, 0x7c,
+ 0x7e, 0x1e, 0x78, 0x00, 0x7c, 0x82, 0x4f, 0x30,
+ 0x00, 0x7c, 0x89, 0x34, 0xbe, 0x00, 0x7c, 0x90,
+ 0x1e, 0xa9, 0x00, 0x7c, 0xae, 0x1e, 0xaa, 0x00,
+ 0x7c, 0xbe, 0x0a, 0x5e, 0x00, 0x7c, 0xd6, 0x0c,
+ 0x76, 0x00, 0x7c, 0xf2, 0x35, 0x06, 0x00, 0x7d,
+ 0x04, 0x36, 0xee, 0x00, 0x7d, 0x09, 0x4e, 0xdc,
+ 0x00, 0x7d, 0x0b, 0x36, 0xec, 0x00, 0x7d, 0x0d,
+ 0x36, 0x94, 0x00, 0x7d, 0x1a, 0x35, 0x91, 0x00,
+ 0x7d, 0x1b, 0x34, 0xbf, 0x00, 0x7d, 0x42, 0x35,
+ 0xf8, 0x00, 0x7d, 0x46, 0x37, 0x63, 0x00, 0x7d,
+ 0x5c, 0x21, 0x90, 0x00, 0x7d, 0x5e, 0x34, 0x84,
+ 0x00, 0x7d, 0x63, 0x37, 0x64, 0x00, 0x7d, 0x73,
+ 0x35, 0x07, 0x00, 0x7d, 0x9b, 0x1e, 0xab, 0x00,
+ 0x7d, 0x9f, 0x1e, 0xad, 0x00, 0x7d, 0xae, 0x1e,
+ 0xac, 0x00, 0x7d, 0xb2, 0x4e, 0xdd, 0x00, 0x7d,
+ 0xcb, 0x34, 0xb6, 0x00, 0x7d, 0xcf, 0x34, 0xa0,
+ 0x00, 0x7d, 0xdd, 0x35, 0x08, 0x00, 0x7d, 0xe8,
+ 0x36, 0xbf, 0x00, 0x7d, 0xe9, 0x35, 0x7a, 0x00,
+ 0x7d, 0xef, 0x34, 0x62, 0x00, 0x7d, 0xf4, 0x0f,
+ 0xc5, 0x00, 0x7e, 0x09, 0x47, 0xbe, 0x00, 0x7e,
+ 0x1b, 0x36, 0x9b, 0x00, 0x7e, 0x22, 0x37, 0x65,
+ 0x00, 0x7e, 0x2b, 0x36, 0xc8, 0x00, 0x7e, 0x35,
+ 0x35, 0x09, 0x00, 0x7e, 0x41, 0x34, 0x40, 0x00,
+ 0x7e, 0x43, 0x37, 0x69, 0x00, 0x7e, 0x6d, 0x36,
+ 0xe1, 0x00, 0x7e, 0x8c, 0x37, 0x6a, 0x00, 0x7f,
+ 0x3e, 0x4e, 0xdf, 0x00, 0x7f, 0x50, 0x37, 0x6b,
+ 0x00, 0x7f, 0x61, 0x3c, 0x28, 0x00, 0x7f, 0x6a,
+ 0x34, 0x89, 0x00, 0x7f, 0x6e, 0x36, 0x60, 0x00,
+ 0x7f, 0x72, 0x09, 0x7a, 0x00, 0x7f, 0x80, 0x56,
+ 0xda, 0x00, 0x7f, 0x8a, 0x0f, 0x3d, 0x00, 0x7f,
+ 0xa1, 0x36, 0x3d, 0x00, 0x7f, 0xae, 0x35, 0x0a,
+ 0x00, 0x7f, 0xbd, 0x04, 0xcb, 0x00, 0x7f, 0xc1,
+ 0x34, 0x6a, 0x00, 0x7f, 0xc5, 0x37, 0x6f, 0x00,
+ 0x7f, 0xc6, 0x37, 0x70, 0x00, 0x7f, 0xcc, 0x37,
+ 0x01, 0x00, 0x7f, 0xd2, 0x35, 0xf9, 0x00, 0x7f,
+ 0xd4, 0x1e, 0xae, 0x00, 0x7f, 0xe0, 0x1e, 0x20,
+ 0x00, 0x7f, 0xe1, 0x35, 0x0b, 0x00, 0x7f, 0xe9,
+ 0x1f, 0x3e, 0x00, 0x7f, 0xeb, 0x1d, 0xe9, 0x00,
+ 0x7f, 0xf0, 0x1d, 0xe8, 0x00, 0x7f, 0xfb, 0x36,
+ 0xd8, 0x00, 0x7f, 0xfc, 0x34, 0xc8, 0x00, 0x80,
+ 0x00, 0x1e, 0x7e, 0x00, 0x80, 0x03, 0x34, 0x85,
+ 0x00, 0x80, 0x05, 0x34, 0x25, 0x00, 0x80, 0x12,
+ 0x4e, 0xe1, 0x00, 0x80, 0x15, 0x35, 0xca, 0x00,
+ 0x80, 0x17, 0x36, 0xea, 0x00, 0x80, 0x36, 0x34,
+ 0xc7, 0x00, 0x80, 0x56, 0x36, 0x2d, 0x00, 0x80,
+ 0x5a, 0x35, 0x0c, 0x00, 0x80, 0x5f, 0x35, 0x0d,
+ 0x00, 0x80, 0x61, 0x34, 0xa1, 0x00, 0x80, 0x6f,
+ 0x34, 0xcd, 0x00, 0x80, 0x70, 0x35, 0x0f, 0x00,
+ 0x80, 0x71, 0x3c, 0x29, 0x00, 0x80, 0x73, 0x35,
+ 0x0e, 0x00, 0x80, 0x74, 0x34, 0xa7, 0x00, 0x80,
+ 0x76, 0x35, 0x10, 0x00, 0x80, 0x77, 0x34, 0x9a,
+ 0x00, 0x80, 0x7e, 0x34, 0xce, 0x00, 0x80, 0x87,
+ 0x36, 0x9c, 0x00, 0x80, 0x89, 0x36, 0x8f, 0x00,
+ 0x80, 0x96, 0x36, 0x0e, 0x00, 0x80, 0x9e, 0x3c,
+ 0x2a, 0x00, 0x80, 0xa9, 0x35, 0xb8, 0x00, 0x80,
+ 0xba, 0x36, 0x97, 0x00, 0x80, 0xd6, 0x4e, 0xe3,
+ 0x00, 0x80, 0xde, 0x36, 0xc9, 0x00, 0x81, 0x06,
+ 0x36, 0x34, 0x00, 0x81, 0x08, 0x34, 0xc6, 0x00,
+ 0x81, 0x09, 0x4e, 0xe4, 0x00, 0x81, 0x29, 0x4e,
+ 0xe5, 0x00, 0x81, 0x53, 0x35, 0x11, 0x00, 0x81,
+ 0x54, 0x35, 0xcb, 0x00, 0x81, 0x70, 0x35, 0xd1,
+ 0x00, 0x81, 0x71, 0x4f, 0x33, 0x00, 0x81, 0x7f,
+ 0x1e, 0x30, 0x00, 0x81, 0x8a, 0x35, 0x12, 0x00,
+ 0x81, 0xb5, 0x35, 0x13, 0x00, 0x81, 0xcd, 0x35,
+ 0x14, 0x00, 0x81, 0xed, 0x34, 0x26, 0x00, 0x82,
+ 0x00, 0x57, 0x0f, 0x00, 0x82, 0x0c, 0x4e, 0xe6,
+ 0x00, 0x82, 0x18, 0x35, 0x7f, 0x00, 0x82, 0x1b,
+ 0x4e, 0xe7, 0x00, 0x82, 0x1c, 0x34, 0x93, 0x00,
+ 0x82, 0x1f, 0x35, 0xb3, 0x00, 0x82, 0x2e, 0x1e,
+ 0xaf, 0x00, 0x82, 0x39, 0x34, 0x9f, 0x00, 0x82,
+ 0x40, 0x4e, 0xe8, 0x00, 0x82, 0x47, 0x34, 0xab,
+ 0x00, 0x82, 0x58, 0x37, 0x74, 0x00, 0x82, 0x79,
+ 0x37, 0x77, 0x00, 0x82, 0x8d, 0x1e, 0xb0, 0x00,
+ 0x82, 0x92, 0x4f, 0x44, 0x00, 0x82, 0xa6, 0x1f,
+ 0x19, 0x00, 0x82, 0xb1, 0x35, 0x62, 0x00, 0x82,
+ 0xbd, 0x05, 0x6a, 0x00, 0x82, 0xc5, 0x35, 0x77,
+ 0x00, 0x82, 0xd2, 0x1e, 0xb1, 0x00, 0x82, 0xe3,
+ 0x37, 0x78, 0x00, 0x83, 0x23, 0x1e, 0xb2, 0x00,
+ 0x83, 0x28, 0x1f, 0x1a, 0x00, 0x83, 0x52, 0x35,
+ 0xcc, 0x00, 0x83, 0x75, 0x1e, 0xb3, 0x00, 0x83,
+ 0xbd, 0x37, 0x7c, 0x00, 0x83, 0xd3, 0x35, 0x63,
+ 0x00, 0x83, 0xd4, 0x4e, 0xea, 0x00, 0x83, 0xdc,
+ 0x35, 0xda, 0x00, 0x83, 0xdf, 0x1e, 0x4b, 0x00,
+ 0x83, 0xf2, 0x35, 0x15, 0x00, 0x84, 0x0c, 0x36,
+ 0xca, 0x00, 0x84, 0x0f, 0x4e, 0xeb, 0x00, 0x84,
+ 0x20, 0x37, 0x7b, 0x00, 0x84, 0x22, 0x1f, 0x3f,
+ 0x00, 0x84, 0x57, 0x34, 0x37, 0x00, 0x84, 0x5b,
+ 0x1d, 0xe4, 0x00, 0x84, 0x5c, 0x57, 0x45, 0x00,
+ 0x84, 0x7a, 0x34, 0xba, 0x00, 0x84, 0xea, 0x4e,
+ 0xed, 0x00, 0x84, 0xec, 0x1e, 0x72, 0x00, 0x84,
+ 0xee, 0x0f, 0xc7, 0x00, 0x84, 0xf4, 0x37, 0x7d,
+ 0x00, 0x85, 0x11, 0x36, 0xbd, 0x00, 0x85, 0x17,
+ 0x1e, 0xb4, 0x00, 0x85, 0x3d, 0x1e, 0x6d, 0x00,
+ 0x85, 0x43, 0x36, 0xa6, 0x00, 0x85, 0x51, 0x4e,
+ 0xef, 0x00, 0x85, 0x55, 0x35, 0x16, 0x00, 0x85,
+ 0x5d, 0x57, 0x64, 0x00, 0x85, 0x63, 0x4e, 0xf0,
+ 0x00, 0x85, 0x84, 0x36, 0x99, 0x00, 0x85, 0x87,
+ 0x37, 0x7f, 0x00, 0x85, 0xa9, 0x1e, 0x08, 0x00,
+ 0x85, 0xaf, 0x1e, 0x15, 0x00, 0x85, 0xcf, 0x4e,
+ 0xf1, 0x00, 0x85, 0xd5, 0x35, 0x17, 0x00, 0x85,
+ 0xe4, 0x36, 0x85, 0x00, 0x85, 0xf7, 0x1e, 0x16,
+ 0x00, 0x86, 0x12, 0x21, 0xa4, 0x00, 0x86, 0x2d,
+ 0x37, 0x04, 0x00, 0x86, 0x4e, 0x4e, 0xf2, 0x00,
+ 0x86, 0x50, 0x35, 0x8c, 0x00, 0x86, 0x54, 0x4f,
+ 0x32, 0x00, 0x86, 0x5c, 0x0f, 0x82, 0x00, 0x86,
+ 0x5e, 0x35, 0xa6, 0x00, 0x86, 0x62, 0x4e, 0xf3,
+ 0x00, 0x86, 0x8a, 0x4e, 0xf4, 0x00, 0x86, 0xdb,
+ 0x34, 0x5e, 0x00, 0x86, 0xf8, 0x1e, 0x35, 0x00,
+ 0x87, 0x03, 0x4f, 0x48, 0x00, 0x87, 0x1a, 0x35,
+ 0x18, 0x00, 0x87, 0x37, 0x37, 0x82, 0x00, 0x87,
+ 0x3b, 0x37, 0x83, 0x00, 0x87, 0x55, 0x1e, 0x1d,
+ 0x00, 0x87, 0x59, 0x1f, 0x40, 0x00, 0x87, 0x82,
+ 0x1e, 0xb6, 0x00, 0x87, 0xa3, 0x57, 0xaa, 0x00,
+ 0x87, 0xbd, 0x37, 0x85, 0x00, 0x87, 0xd2, 0x1e,
+ 0xb7, 0x00, 0x88, 0x03, 0x3b, 0x03, 0x00, 0x88,
+ 0x05, 0x37, 0x84, 0x00, 0x88, 0x0e, 0x1f, 0x41,
+ 0x00, 0x88, 0x36, 0x35, 0x19, 0x00, 0x88, 0x42,
+ 0x4e, 0xf5, 0x00, 0x88, 0x46, 0x35, 0xfa, 0x00,
+ 0x88, 0x4b, 0x57, 0xc3, 0x00, 0x88, 0x53, 0x35,
+ 0xfd, 0x00, 0x88, 0x5b, 0x34, 0x66, 0x00, 0x88,
+ 0x5e, 0x35, 0x53, 0x00, 0x88, 0x63, 0x35, 0x48,
+ 0x00, 0x88, 0x70, 0x36, 0x27, 0x00, 0x88, 0x77,
+ 0x4e, 0xf6, 0x00, 0x88, 0x9e, 0x35, 0x1a, 0x00,
+ 0x88, 0xd8, 0x35, 0x1b, 0x00, 0x88, 0xf4, 0x35,
+ 0x1c, 0x00, 0x89, 0x0a, 0x1e, 0xb8, 0x00, 0x89,
+ 0x10, 0x34, 0x13, 0x00, 0x89, 0x1c, 0x37, 0xcb,
+ 0x00, 0x89, 0x2b, 0x35, 0x1d, 0x00, 0x89, 0x3b,
+ 0x35, 0x1e, 0x00, 0x89, 0x41, 0x4e, 0xf7, 0x00,
+ 0x89, 0x56, 0x1d, 0xdd, 0x00, 0x89, 0x6a, 0x35,
+ 0x1f, 0x00, 0x89, 0x6f, 0x35, 0x20, 0x00, 0x89,
+ 0x81, 0x36, 0xff, 0x00, 0x89, 0x86, 0x36, 0xb8,
+ 0x00, 0x89, 0x87, 0x36, 0x95, 0x00, 0x89, 0x96,
+ 0x34, 0x22, 0x00, 0x89, 0xaa, 0x34, 0x9b, 0x00,
+ 0x89, 0xaf, 0x1e, 0xb9, 0x00, 0x89, 0xbd, 0x37,
+ 0x8a, 0x00, 0x89, 0xd2, 0x05, 0xaf, 0x00, 0x8a,
+ 0x0a, 0x36, 0x24, 0x00, 0x8a, 0x12, 0x37, 0xd7,
+ 0x00, 0x8a, 0x1d, 0x35, 0x21, 0x00, 0x8a, 0x1f,
+ 0x34, 0x96, 0x00, 0x8a, 0x3b, 0x1e, 0x3c, 0x00,
+ 0x8a, 0x55, 0x36, 0xaf, 0x00, 0x8a, 0x6e, 0x1e,
+ 0x28, 0x00, 0x8a, 0x8d, 0x36, 0x92, 0x00, 0x8a,
+ 0x95, 0x34, 0xa3, 0x00, 0x8a, 0xa0, 0x36, 0x2f,
+ 0x00, 0x8a, 0xa4, 0x35, 0xc2, 0x00, 0x8a, 0xb9,
+ 0x34, 0xb7, 0x00, 0x8a, 0xbf, 0x36, 0x6d, 0x00,
+ 0x8a, 0xcb, 0x36, 0x30, 0x00, 0x8a, 0xdb, 0x37,
+ 0x8b, 0x00, 0x8a, 0xde, 0x1e, 0xba, 0x00, 0x8a,
+ 0xed, 0x0f, 0x0b, 0x00, 0x8a, 0xee, 0x35, 0xe3,
+ 0x00, 0x8a, 0xf8, 0x09, 0x7e, 0x00, 0x8a, 0xfa,
+ 0x1d, 0xfe, 0x00, 0x8b, 0x01, 0x04, 0xfc, 0x00,
+ 0x8b, 0x04, 0x36, 0x86, 0x00, 0x8b, 0x0e, 0x1e,
+ 0x56, 0x00, 0x8b, 0x19, 0x35, 0xb9, 0x00, 0x8b,
+ 0x1b, 0x35, 0xcd, 0x00, 0x8b, 0x1d, 0x34, 0x8d,
+ 0x00, 0x8b, 0x2c, 0x1e, 0x69, 0x00, 0x8b, 0x39,
+ 0x06, 0xd8, 0x00, 0x8b, 0x3e, 0x37, 0x8c, 0x00,
+ 0x8b, 0x41, 0x1e, 0xbb, 0x00, 0x8b, 0x56, 0x4e,
+ 0xf8, 0x00, 0x8b, 0x5a, 0x37, 0x8d, 0x00, 0x8b,
+ 0x5c, 0x4e, 0xfa, 0x00, 0x8b, 0x7f, 0x52, 0x52,
+ 0x00, 0x8c, 0x6a, 0x4e, 0xfd, 0x00, 0x8c, 0x79,
+ 0x4e, 0xfe, 0x00, 0x8c, 0x9b, 0x58, 0x37, 0x00,
+ 0x8c, 0xa0, 0x36, 0xb5, 0x00, 0x8c, 0xa7, 0x34,
+ 0xb8, 0x00, 0x8c, 0xa8, 0x35, 0x64, 0x00, 0x8c,
+ 0xab, 0x34, 0x72, 0x00, 0x8c, 0xc7, 0x35, 0xe5,
+ 0x00, 0x8c, 0xca, 0x36, 0x4c, 0x00, 0x8c, 0xd3,
+ 0x0d, 0xc2, 0x00, 0x8c, 0xed, 0x1e, 0x4c, 0x00,
+ 0x8c, 0xfc, 0x34, 0x86, 0x00, 0x8d, 0x05, 0x35,
+ 0x22, 0x00, 0x8d, 0x08, 0x34, 0x34, 0x00, 0x8d,
+ 0x0f, 0x35, 0x23, 0x00, 0x8d, 0x67, 0x4f, 0x00,
+ 0x00, 0x8d, 0x70, 0x36, 0x46, 0x00, 0x8d, 0x73,
+ 0x37, 0x8e, 0x00, 0x8d, 0x77, 0x35, 0x88, 0x00,
+ 0x8d, 0x99, 0x37, 0x8f, 0x00, 0x8d, 0xda, 0x1e,
+ 0xbc, 0x00, 0x8d, 0xdd, 0x35, 0x94, 0x00, 0x8d,
+ 0xf3, 0x34, 0xa8, 0x00, 0x8e, 0x09, 0x1e, 0xbd,
+ 0x00, 0x8e, 0x34, 0x37, 0x91, 0x00, 0x8e, 0x4a,
+ 0x37, 0x92, 0x00, 0x8e, 0x8d, 0x36, 0xef, 0x00,
+ 0x8e, 0x91, 0x35, 0x25, 0x00, 0x8e, 0xa1, 0x35,
+ 0x26, 0x00, 0x8e, 0xcc, 0x34, 0x76, 0x00, 0x8e,
+ 0xd4, 0x3b, 0x4a, 0x00, 0x8f, 0x03, 0x4f, 0x02,
+ 0x00, 0x8f, 0x13, 0x1e, 0xbe, 0x00, 0x8f, 0x29,
+ 0x34, 0xb0, 0x00, 0x8f, 0x2f, 0x34, 0x90, 0x00,
+ 0x8f, 0x38, 0x36, 0xf5, 0x00, 0x8f, 0x44, 0x35,
+ 0x75, 0x00, 0x8f, 0xb6, 0x3c, 0x2b, 0x00, 0x8f,
+ 0xbb, 0x20, 0x4b, 0x00, 0x8f, 0xbc, 0x35, 0xd3,
+ 0x00, 0x8f, 0xbf, 0x1e, 0x37, 0x00, 0x8f, 0xc2,
+ 0x1d, 0xd6, 0x00, 0x8f, 0xc4, 0x1f, 0x2c, 0x00,
+ 0x8f, 0xc5, 0x36, 0x26, 0x00, 0x8f, 0xc6, 0x3b,
+ 0x51, 0x00, 0x8f, 0xce, 0x35, 0xae, 0x00, 0x8f,
+ 0xd1, 0x35, 0xa2, 0x00, 0x8f, 0xd4, 0x36, 0xc0,
+ 0x00, 0x8f, 0xe6, 0x1d, 0xdf, 0x00, 0x8f, 0xe9,
+ 0x1e, 0xc0, 0x00, 0x8f, 0xea, 0x1e, 0xbf, 0x00,
+ 0x8f, 0xeb, 0x36, 0x9a, 0x00, 0x8f, 0xed, 0x36,
+ 0x7b, 0x00, 0x8f, 0xef, 0x37, 0x93, 0x00, 0x8f,
+ 0xf0, 0x35, 0xfe, 0x00, 0x8f, 0xf6, 0x4f, 0x06,
+ 0x00, 0x8f, 0xf7, 0x36, 0xe6, 0x00, 0x8f, 0xfa,
+ 0x37, 0x95, 0x00, 0x8f, 0xfd, 0x36, 0x72, 0x00,
+ 0x90, 0x00, 0x36, 0x51, 0x00, 0x90, 0x01, 0x36,
+ 0x47, 0x00, 0x90, 0x03, 0x34, 0xad, 0x00, 0x90,
+ 0x06, 0x35, 0x8d, 0x00, 0x90, 0x0e, 0x35, 0x28,
+ 0x00, 0x90, 0x0f, 0x36, 0x88, 0x00, 0x90, 0x10,
+ 0x36, 0x64, 0x00, 0x90, 0x14, 0x36, 0x7e, 0x00,
+ 0x90, 0x17, 0x1e, 0x1f, 0x00, 0x90, 0x19, 0x1e,
+ 0x5c, 0x00, 0x90, 0x1a, 0x36, 0x73, 0x00, 0x90,
+ 0x1d, 0x1e, 0x22, 0x00, 0x90, 0x1e, 0x37, 0x96,
+ 0x00, 0x90, 0x1f, 0x36, 0x4b, 0x00, 0x90, 0x20,
+ 0x36, 0x49, 0x00, 0x90, 0x22, 0x20, 0x4a, 0x00,
+ 0x90, 0x23, 0x0f, 0xc8, 0x00, 0x90, 0x2e, 0x36,
+ 0x52, 0x00, 0x90, 0x31, 0x35, 0xfb, 0x00, 0x90,
+ 0x32, 0x36, 0x1f, 0x00, 0x90, 0x35, 0x37, 0x97,
+ 0x00, 0x90, 0x38, 0x34, 0x08, 0x00, 0x90, 0x39,
+ 0x36, 0x58, 0x00, 0x90, 0x3c, 0x1e, 0x67, 0x00,
+ 0x90, 0x41, 0x1e, 0x53, 0x00, 0x90, 0x42, 0x34,
+ 0x9c, 0x00, 0x90, 0x47, 0x35, 0xa8, 0x00, 0x90,
+ 0x4a, 0x36, 0xfc, 0x00, 0x90, 0x4b, 0x35, 0x51,
+ 0x00, 0x90, 0x4d, 0x36, 0xc1, 0x00, 0x90, 0x4e,
+ 0x35, 0x65, 0x00, 0x90, 0x50, 0x37, 0x98, 0x00,
+ 0x90, 0x52, 0x35, 0x27, 0x00, 0x90, 0x53, 0x36,
+ 0x8b, 0x00, 0x90, 0x54, 0x36, 0x58, 0x00, 0x90,
+ 0x55, 0x34, 0x63, 0x00, 0x90, 0x58, 0x1e, 0xc1,
+ 0x00, 0x90, 0x5c, 0x1e, 0x2e, 0x00, 0x90, 0x60,
+ 0x35, 0x5a, 0x00, 0x90, 0x61, 0x1e, 0x2a, 0x00,
+ 0x90, 0x63, 0x35, 0xba, 0x00, 0x90, 0x69, 0x36,
+ 0x7a, 0x00, 0x90, 0x6d, 0x36, 0x48, 0x00, 0x90,
+ 0x6e, 0x1e, 0x0e, 0x00, 0x90, 0x75, 0x36, 0x00,
+ 0x00, 0x90, 0x77, 0x36, 0x40, 0x00, 0x90, 0x78,
+ 0x36, 0x3f, 0x00, 0x90, 0x7a, 0x35, 0x4a, 0x00,
+ 0x90, 0x7c, 0x1e, 0x80, 0x00, 0x90, 0x7f, 0x36,
+ 0xa7, 0x00, 0x90, 0x81, 0x37, 0x9a, 0x00, 0x90,
+ 0x83, 0x37, 0x5c, 0x00, 0x90, 0x84, 0x35, 0x7c,
+ 0x00, 0x90, 0x87, 0x37, 0x94, 0x00, 0x90, 0x89,
+ 0x34, 0x5f, 0x00, 0x90, 0x8a, 0x37, 0x9b, 0x00,
+ 0x90, 0xa3, 0x1e, 0x55, 0x00, 0x90, 0xa6, 0x36,
+ 0xcb, 0x00, 0x90, 0xa8, 0x4f, 0x0b, 0x00, 0x90,
+ 0xaa, 0x34, 0x8e, 0x00, 0x90, 0xf7, 0x35, 0x9d,
+ 0x00, 0x90, 0xfd, 0x0c, 0x4e, 0x00, 0x91, 0x2d,
+ 0x1e, 0x44, 0x00, 0x91, 0x30, 0x35, 0x29, 0x00,
+ 0x91, 0x4b, 0x1e, 0x12, 0x00, 0x91, 0x4c, 0x35,
+ 0xf2, 0x00, 0x91, 0x4d, 0x4f, 0x0c, 0x00, 0x91,
+ 0x56, 0x35, 0x2a, 0x00, 0x91, 0x58, 0x35, 0x2b,
+ 0x00, 0x91, 0x65, 0x35, 0x2c, 0x00, 0x91, 0x72,
+ 0x35, 0x2e, 0x00, 0x91, 0x73, 0x35, 0x2d, 0x00,
+ 0x91, 0x77, 0x35, 0xd0, 0x00, 0x91, 0xa2, 0x35,
+ 0x2f, 0x00, 0x91, 0xaa, 0x35, 0x31, 0x00, 0x91,
+ 0xaf, 0x35, 0x30, 0x00, 0x91, 0xb1, 0x36, 0x9f,
+ 0x00, 0x91, 0xb4, 0x35, 0x32, 0x00, 0x91, 0xba,
+ 0x35, 0x33, 0x00, 0x91, 0xc1, 0x1e, 0xc3, 0x00,
+ 0x91, 0xc7, 0x1e, 0x05, 0x00, 0x91, 0xdc, 0x4f,
+ 0x42, 0x00, 0x91, 0xe3, 0x36, 0x75, 0x00, 0x91,
+ 0xfc, 0x3c, 0x2c, 0x00, 0x92, 0x37, 0x34, 0x7d,
+ 0x00, 0x92, 0x5b, 0x34, 0x69, 0x00, 0x92, 0xe9,
+ 0x4f, 0x0d, 0x00, 0x93, 0x06, 0x1e, 0x0a, 0x00,
+ 0x93, 0x35, 0x4f, 0x0e, 0x00, 0x93, 0x65, 0x3b,
+ 0x86, 0x00, 0x93, 0x75, 0x4f, 0x34, 0x00, 0x93,
+ 0x8b, 0x4f, 0x0f, 0x00, 0x93, 0x8c, 0x35, 0x76,
+ 0x00, 0x93, 0x96, 0x35, 0xd5, 0x00, 0x93, 0x9a,
+ 0x1e, 0x41, 0x00, 0x93, 0xa1, 0x59, 0x04, 0x00,
+ 0x93, 0xae, 0x34, 0x3a, 0x00, 0x93, 0xdd, 0x37,
+ 0xae, 0x00, 0x94, 0x3a, 0x4f, 0x10, 0x00, 0x94,
+ 0x53, 0x1e, 0x79, 0x00, 0x94, 0x77, 0x35, 0x34,
+ 0x00, 0x95, 0x92, 0x35, 0x7d, 0x00, 0x95, 0xab,
+ 0x3b, 0x9a, 0x00, 0x95, 0xbb, 0x1e, 0xc4, 0x00,
+ 0x95, 0xbc, 0x37, 0xaf, 0x00, 0x95, 0xcd, 0x4f,
+ 0x11, 0x00, 0x96, 0x2a, 0x4f, 0x12, 0x00, 0x96,
+ 0x4d, 0x34, 0x87, 0x00, 0x96, 0x86, 0x34, 0x51,
+ 0x00, 0x96, 0x8a, 0x36, 0x53, 0x00, 0x96, 0x94,
+ 0x35, 0x73, 0x00, 0x96, 0x98, 0x35, 0x35, 0x00,
+ 0x96, 0x99, 0x4f, 0x31, 0x00, 0x96, 0xa3, 0x34,
+ 0xca, 0x00, 0x96, 0xa7, 0x4f, 0x14, 0x00, 0x96,
+ 0xb2, 0x37, 0xb1, 0x00, 0x96, 0xbb, 0x36, 0x35,
+ 0x00, 0x96, 0xc5, 0x34, 0x6c, 0x00, 0x96, 0xc7,
+ 0x35, 0xbe, 0x00, 0x96, 0xd9, 0x34, 0xd5, 0x00,
+ 0x96, 0xda, 0x59, 0x3b, 0x00, 0x96, 0xe3, 0x0c,
+ 0xc9, 0x00, 0x96, 0xe8, 0x35, 0x4d, 0x00, 0x96,
+ 0xea, 0x36, 0x39, 0x00, 0x96, 0xf0, 0x34, 0xc0,
+ 0x00, 0x97, 0x21, 0x59, 0x41, 0x00, 0x97, 0x24,
+ 0x1e, 0xc6, 0x00, 0x97, 0x3d, 0x35, 0x36, 0x00,
+ 0x97, 0x55, 0x21, 0xf8, 0x00, 0x97, 0x56, 0x21,
+ 0x8b, 0x00, 0x97, 0x59, 0x37, 0xb2, 0x00, 0x97,
+ 0x5c, 0x36, 0x31, 0x00, 0x97, 0x60, 0x1e, 0xc7,
+ 0x00, 0x97, 0x6d, 0x1e, 0xc8, 0x00, 0x97, 0x71,
+ 0x1e, 0x1e, 0x00, 0x97, 0x74, 0x1d, 0xf3, 0x00,
+ 0x97, 0x84, 0x1d, 0xe5, 0x00, 0x97, 0x98, 0x1e,
+ 0x1c, 0x00, 0x97, 0xad, 0x4f, 0x43, 0x00, 0x97,
+ 0xd3, 0x35, 0x7e, 0x00, 0x97, 0xde, 0x3c, 0x2e,
+ 0x00, 0x97, 0xf3, 0x35, 0x60, 0x00, 0x97, 0xff,
+ 0x34, 0x19, 0x00, 0x98, 0x0c, 0x35, 0x39, 0x00,
+ 0x98, 0x11, 0x34, 0x74, 0x00, 0x98, 0x12, 0x34,
+ 0xb2, 0x00, 0x98, 0x13, 0x1e, 0x54, 0x00, 0x98,
+ 0x24, 0x1e, 0xc9, 0x00, 0x98, 0x3b, 0x0d, 0xc3,
+ 0x00, 0x98, 0x5e, 0x0f, 0xa8, 0x00, 0x98, 0x67,
+ 0x35, 0xbf, 0x00, 0x98, 0x73, 0x35, 0x3a, 0x00,
+ 0x98, 0xc3, 0x35, 0x3b, 0x00, 0x98, 0xdf, 0x36,
+ 0x17, 0x00, 0x98, 0xe2, 0x35, 0x89, 0x00, 0x98,
+ 0xeb, 0x37, 0xb4, 0x00, 0x98, 0xef, 0x0d, 0x67,
+ 0x00, 0x98, 0xf4, 0x1d, 0xd2, 0x00, 0x98, 0xfc,
+ 0x21, 0xfc, 0x00, 0x98, 0xfd, 0x36, 0xcd, 0x00,
+ 0x98, 0xfe, 0x36, 0x14, 0x00, 0x99, 0x03, 0x37,
+ 0xb5, 0x00, 0x99, 0x05, 0x1e, 0x77, 0x00, 0x99,
+ 0x09, 0x37, 0xb6, 0x00, 0x99, 0x0a, 0x37, 0x00,
+ 0x00, 0x99, 0x0c, 0x1d, 0xdb, 0x00, 0x99, 0x10,
+ 0x1f, 0x22, 0x00, 0x99, 0x13, 0x35, 0x68, 0x00,
+ 0x99, 0x21, 0x4f, 0x18, 0x00, 0x99, 0x28, 0x21,
+ 0xfe, 0x00, 0x99, 0x45, 0x37, 0xb7, 0x00, 0x99,
+ 0x4b, 0x37, 0xb9, 0x00, 0x99, 0x57, 0x1f, 0x20,
+ 0x00, 0x99, 0xc1, 0x4f, 0x40, 0x00, 0x99, 0xd0,
+ 0x36, 0x67, 0x00, 0x9a, 0x19, 0x1f, 0x43, 0x00,
+ 0x9a, 0x30, 0x36, 0x89, 0x00, 0x9a, 0x45, 0x35,
+ 0x3c, 0x00, 0x9a, 0x4a, 0x59, 0x88, 0x00, 0x9a,
+ 0x5f, 0x37, 0xbb, 0x00, 0x9a, 0x65, 0x37, 0xbc,
+ 0x00, 0x9a, 0xef, 0x37, 0xbd, 0x00, 0x9b, 0x18,
+ 0x37, 0xbe, 0x00, 0x9b, 0x2d, 0x34, 0x3c, 0x00,
+ 0x9b, 0x2e, 0x1e, 0xca, 0x00, 0x9b, 0x35, 0x59,
+ 0xa4, 0x00, 0x9b, 0x4d, 0x35, 0x3d, 0x00, 0x9b,
+ 0x54, 0x36, 0xdb, 0x00, 0x9b, 0x58, 0x35, 0x3e,
+ 0x00, 0x9b, 0x97, 0x1e, 0xcb, 0x00, 0x9b, 0xa8,
+ 0x4f, 0x1a, 0x00, 0x9b, 0xab, 0x4f, 0x38, 0x00,
+ 0x9b, 0xae, 0x4f, 0x1b, 0x00, 0x9b, 0xb9, 0x4f,
+ 0x1c, 0x00, 0x9b, 0xc6, 0x35, 0x3f, 0x00, 0x9b,
+ 0xd6, 0x1e, 0x09, 0x00, 0x9b, 0xdb, 0x36, 0x54,
+ 0x00, 0x9b, 0xe1, 0x35, 0x40, 0x00, 0x9b, 0xf1,
+ 0x35, 0x41, 0x00, 0x9b, 0xf2, 0x1e, 0xcc, 0x00,
+ 0x9c, 0x08, 0x4f, 0x1d, 0x00, 0x9c, 0x24, 0x4f,
+ 0x1e, 0x00, 0x9c, 0x2f, 0x1d, 0xd4, 0x00, 0x9c,
+ 0x3b, 0x4f, 0x1f, 0x00, 0x9c, 0x48, 0x1e, 0x39,
+ 0x00, 0x9c, 0x52, 0x1e, 0x74, 0x00, 0x9c, 0x57,
+ 0x37, 0x0c, 0x00, 0x9c, 0xe6, 0x4f, 0x21, 0x00,
+ 0x9d, 0x07, 0x1e, 0x4f, 0x00, 0x9d, 0x08, 0x37,
+ 0xc1, 0x00, 0x9d, 0x09, 0x37, 0xc0, 0x00, 0x9d,
+ 0x48, 0x35, 0x42, 0x00, 0x9d, 0x60, 0x1e, 0x03,
+ 0x00, 0x9d, 0x6c, 0x36, 0xce, 0x00, 0x9d, 0xb4,
+ 0x0b, 0xfd, 0x00, 0x9d, 0xbf, 0x59, 0xde, 0x00,
+ 0x9d, 0xc0, 0x4f, 0x22, 0x00, 0x9d, 0xc2, 0x4f,
+ 0x23, 0x00, 0x9d, 0xcf, 0x35, 0x43, 0x00, 0x9e,
+ 0x97, 0x34, 0xcc, 0x00, 0x9e, 0x9f, 0x34, 0xcb,
+ 0x00, 0x9e, 0xa5, 0x37, 0xc2, 0x00, 0x9e, 0xaa,
+ 0x1e, 0xcd, 0x00, 0x9e, 0xad, 0x1f, 0x44, 0x00,
+ 0x9e, 0xbb, 0x36, 0xdc, 0x00, 0x9e, 0xbf, 0x36,
+ 0xe2, 0x00, 0x9e, 0xcc, 0x37, 0xc3, 0x00, 0x9e,
+ 0xdb, 0x1e, 0x31, 0x00, 0x9f, 0x08, 0x35, 0x44,
+ 0x00, 0x9f, 0x3b, 0x36, 0xa9, 0x00, 0x9f, 0x4a,
+ 0x37, 0xc5, 0x00, 0x9f, 0x4b, 0x37, 0x5a, 0x00,
+ 0x9f, 0x4e, 0x35, 0x24, 0x00, 0x9f, 0x67, 0x37,
+ 0xc7, 0x00, 0x9f, 0x8d, 0x37, 0x06, 0x00, 0x9f,
+ 0x9c, 0x1e, 0xce, 0x00, 0x9f, 0x9d, 0x1e, 0xa7,
+ 0x00, 0xfa, 0x11, 0x20, 0xfb, 0x00, 0xfa, 0x24,
+ 0x21, 0xb8, 0x02, 0x35, 0xc4, 0x3c, 0x44, 0x02,
+ 0x36, 0x3a, 0x35, 0x9b, 0x02, 0x38, 0x3d, 0x4f,
+ 0x26, 0x02, 0x42, 0xee, 0x37, 0xc9, 0x02, 0x62,
+ 0x70, 0x37, 0x6e, 0x02, 0x9d, 0x4b, 0x35, 0x96,
+ 0x02, 0x9e, 0x3d, 0x3c, 0x4d, 0x02, 0xa6, 0x1a,
+ 0x37, 0xc8, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x34,
+ 0x02, 0x35, 0x83, 0x00, 0x50, 0x91, 0x35, 0xaf,
+ 0x00, 0x50, 0xca, 0x37, 0x15, 0x00, 0x51, 0x54,
+ 0x37, 0x17, 0x00, 0x51, 0x95, 0x37, 0x18, 0x00,
+ 0x51, 0xb4, 0x35, 0xdb, 0x00, 0x51, 0xde, 0x38,
+ 0x10, 0x00, 0x52, 0x72, 0x4e, 0x76, 0x00, 0x53,
+ 0x7f, 0x1d, 0xed, 0x00, 0x53, 0xa9, 0x1f, 0x1c,
+ 0x00, 0x55, 0x33, 0x37, 0x21, 0x00, 0x55, 0xa9,
+ 0x34, 0xd6, 0x00, 0x55, 0xab, 0x4e, 0x7c, 0x00,
+ 0x55, 0xe4, 0x37, 0x22, 0x00, 0x56, 0xae, 0x4e,
+ 0x7e, 0x00, 0x57, 0xf4, 0x36, 0x13, 0x00, 0x58,
+ 0x5a, 0x20, 0xe6, 0x00, 0x59, 0x51, 0x4e, 0x88,
+ 0x00, 0x59, 0xff, 0x35, 0xe1, 0x00, 0x5a, 0xbe,
+ 0x34, 0xdc, 0x00, 0x5b, 0xb3, 0x35, 0x6b, 0x00,
+ 0x5c, 0x0a, 0x36, 0x4e, 0x00, 0x5c, 0x0f, 0x36,
+ 0x0a, 0x00, 0x5e, 0xca, 0x34, 0x59, 0x00, 0x5e,
+ 0xe3, 0x4e, 0x93, 0x00, 0x5e, 0xf6, 0x35, 0x56,
+ 0x00, 0x60, 0x62, 0x4f, 0x2d, 0x00, 0x60, 0x97,
+ 0x37, 0x30, 0x00, 0x61, 0x67, 0x35, 0xad, 0x00,
+ 0x61, 0x68, 0x34, 0x6e, 0x00, 0x61, 0xb2, 0x4e,
+ 0x98, 0x00, 0x61, 0xf2, 0x36, 0x6a, 0x00, 0x62,
+ 0x49, 0x34, 0xb4, 0x00, 0x66, 0x5f, 0x37, 0x38,
+ 0x00, 0x66, 0xc1, 0x4e, 0xac, 0x00, 0x67, 0x15,
+ 0x36, 0x70, 0x00, 0x67, 0x17, 0x21, 0x29, 0x00,
+ 0x67, 0x1b, 0x36, 0xd5, 0x00, 0x68, 0x5d, 0x36,
+ 0xde, 0x00, 0x68, 0x7a, 0x36, 0xf1, 0x00, 0x69,
+ 0x0d, 0x36, 0x15, 0x00, 0x69, 0x82, 0x34, 0x6f,
+ 0x00, 0x6a, 0xdb, 0x35, 0xa9, 0x00, 0x6b, 0x21,
+ 0x35, 0xe8, 0x00, 0x6c, 0x08, 0x34, 0xf4, 0x00,
+ 0x6c, 0xaa, 0x4e, 0xbb, 0x00, 0x6c, 0xbf, 0x34,
+ 0x68, 0x00, 0x6c, 0xe8, 0x32, 0x45, 0x00, 0x6d,
+ 0x3e, 0x36, 0x96, 0x00, 0x6e, 0x23, 0x34, 0xf6,
+ 0x00, 0x6e, 0xa2, 0x52, 0x4f, 0x00, 0x6e, 0xcb,
+ 0x4e, 0xc1, 0x00, 0x6f, 0x11, 0x37, 0x45, 0x00,
+ 0x6f, 0x5b, 0x4e, 0xc5, 0x00, 0x71, 0x7d, 0x1f,
+ 0x24, 0x00, 0x72, 0x35, 0x35, 0xf0, 0x00, 0x73,
+ 0x36, 0x36, 0xf9, 0x00, 0x73, 0x37, 0x36, 0xfa,
+ 0x00, 0x73, 0xca, 0x4e, 0xcc, 0x00, 0x75, 0x11,
+ 0x35, 0xd2, 0x00, 0x75, 0x15, 0x4f, 0x2b, 0x00,
+ 0x79, 0x53, 0x37, 0x59, 0x00, 0x7a, 0x74, 0x35,
+ 0xb1, 0x00, 0x7b, 0x08, 0x4f, 0x27, 0x00, 0x7b,
+ 0xc0, 0x36, 0x37, 0x00, 0x7c, 0x3e, 0x4f, 0x29,
+ 0x00, 0x7c, 0x50, 0x4e, 0xdb, 0x00, 0x7c, 0x7e,
+ 0x4f, 0x45, 0x00, 0x7d, 0xb2, 0x4e, 0xde, 0x00,
+ 0x7e, 0x22, 0x37, 0x66, 0x00, 0x7e, 0x35, 0x37,
+ 0x68, 0x00, 0x7f, 0xc1, 0x35, 0x5e, 0x00, 0x7f,
+ 0xe1, 0x4e, 0xe0, 0x00, 0x7f, 0xe9, 0x37, 0x71,
+ 0x00, 0x7f, 0xfc, 0x37, 0x02, 0x00, 0x81, 0x08,
+ 0x36, 0xe3, 0x00, 0x82, 0x39, 0x36, 0x3e, 0x00,
+ 0x82, 0x79, 0x37, 0x76, 0x00, 0x82, 0xbd, 0x34,
+ 0x6b, 0x00, 0x83, 0xdf, 0x1f, 0x28, 0x00, 0x85,
+ 0x3d, 0x34, 0xc1, 0x00, 0x86, 0x12, 0x52, 0x51,
+ 0x00, 0x87, 0xd2, 0x1f, 0x42, 0x00, 0x88, 0x05,
+ 0x4f, 0x47, 0x00, 0x88, 0x36, 0x37, 0x87, 0x00,
+ 0x8a, 0x0a, 0x36, 0x25, 0x00, 0x8a, 0x1d, 0x4f,
+ 0x2c, 0x00, 0x8a, 0x95, 0x36, 0x5d, 0x00, 0x8a,
+ 0xee, 0x35, 0xe4, 0x00, 0x8b, 0x56, 0x4e, 0xf9,
+ 0x00, 0x8c, 0xa0, 0x36, 0xb6, 0x00, 0x8c, 0xc7,
+ 0x35, 0xe6, 0x00, 0x8c, 0xca, 0x4e, 0xff, 0x00,
+ 0x8c, 0xfc, 0x35, 0xce, 0x00, 0x8f, 0x44, 0x4f,
+ 0x03, 0x00, 0x8f, 0xc5, 0x4f, 0x04, 0x00, 0x8f,
+ 0xd4, 0x4f, 0x05, 0x00, 0x90, 0x03, 0x36, 0x87,
+ 0x00, 0x90, 0x22, 0x34, 0x60, 0x00, 0x90, 0x38,
+ 0x21, 0xb9, 0x00, 0x90, 0x41, 0x4f, 0x3f, 0x00,
+ 0x90, 0x42, 0x36, 0x28, 0x00, 0x90, 0x55, 0x35,
+ 0x49, 0x00, 0x90, 0x75, 0x36, 0x01, 0x00, 0x90,
+ 0x77, 0x4f, 0x07, 0x00, 0x90, 0x89, 0x37, 0xa1,
+ 0x00, 0x90, 0x8a, 0x37, 0x9c, 0x00, 0x90, 0xa6,
+ 0x36, 0xcc, 0x00, 0x90, 0xaa, 0x35, 0xee, 0x00,
+ 0x92, 0x5b, 0x35, 0x5b, 0x00, 0x96, 0x86, 0x21,
+ 0xee, 0x00, 0x96, 0x98, 0x4f, 0x13, 0x00, 0x96,
+ 0xa3, 0x37, 0x0b, 0x00, 0x96, 0xc5, 0x35, 0x67,
+ 0x00, 0x97, 0x5c, 0x36, 0x32, 0x00, 0x97, 0x60,
+ 0x35, 0x37, 0x00, 0x97, 0x6d, 0x1f, 0x23, 0x00,
+ 0x97, 0x71, 0x35, 0x38, 0x00, 0x97, 0xff, 0x35,
+ 0x9e, 0x00, 0x98, 0xef, 0x4f, 0x25, 0x00, 0x99,
+ 0x0c, 0x34, 0x65, 0x00, 0x99, 0x45, 0x37, 0xb8,
+ 0x00, 0x99, 0x57, 0x35, 0x9f, 0x00, 0x9e, 0x9f,
+ 0x37, 0x0d, 0x00, 0x9f, 0x08, 0x37, 0xc4, 0x00,
+ 0x9f, 0x8d, 0x37, 0x07, 0x02, 0x36, 0x3a, 0x35,
+ 0x9c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x51, 0xde,
+ 0x4e, 0x71, 0x00, 0x53, 0xa9, 0x34, 0x64, 0x00,
+ 0x56, 0xae, 0x4e, 0x7f, 0x00, 0x5b, 0xb3, 0x4e,
+ 0x8f, 0x00, 0x61, 0x68, 0x35, 0x6c, 0x00, 0x61,
+ 0xf2, 0x52, 0x50, 0x00, 0x66, 0x5f, 0x37, 0x39,
+ 0x00, 0x67, 0x17, 0x37, 0x12, 0x00, 0x69, 0x82,
+ 0x35, 0x70, 0x00, 0x75, 0x11, 0x4f, 0x3c, 0x00,
+ 0x83, 0xdf, 0x4e, 0xe9, 0x00, 0x90, 0x77, 0x4f,
+ 0x08, 0x00, 0x90, 0x89, 0x37, 0xa2, 0x00, 0x90,
+ 0x8a, 0x37, 0x9d, 0x00, 0x97, 0xff, 0x4f, 0x15,
+ 0x00, 0x99, 0x0c, 0x35, 0x52, 0x00, 0x99, 0x57,
+ 0x4f, 0x19, 0x00, 0x00, 0x00, 0x06, 0x00, 0x51,
+ 0xde, 0x21, 0x5e, 0x00, 0x53, 0xa9, 0x35, 0x4f,
+ 0x00, 0x61, 0x68, 0x35, 0x6d, 0x00, 0x90, 0x89,
+ 0x37, 0xa3, 0x00, 0x90, 0x8a, 0x37, 0x9e, 0x00,
+ 0x97, 0xff, 0x4f, 0x16, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x53, 0xa9, 0x4f, 0x2f, 0x00, 0x61, 0x68,
+ 0x35, 0x6e, 0x00, 0x90, 0x89, 0x37, 0xa4, 0x00,
+ 0x90, 0x8a, 0x37, 0x9f, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x90, 0x89, 0x37, 0xa5, 0x00, 0x90, 0x8a,
+ 0x37, 0xa0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x90,
+ 0x89, 0x37, 0xa6, 0x00, 0x90, 0x8a, 0x4f, 0x0a,
0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x89, 0x37,
- 0xac, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x89,
- 0x4f, 0x09
+ 0xa7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0x89,
+ 0x37, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90,
+ 0x89, 0x37, 0xa9, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x90, 0x89, 0x37, 0xaa, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x90, 0x89, 0x37, 0xab, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x90, 0x89, 0x37, 0xac, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x90, 0x89, 0x4f, 0x09
};
diff --git a/src/menu.c b/src/menu.c
index eeb0c9a7e5b..c52e9258a15 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -32,10 +32,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "blockinput.h"
#include "buffer.h"
-#ifdef USE_X_TOOLKIT
-#include "../lwlib/lwlib.h"
-#endif
-
#ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
diff --git a/src/minibuf.c b/src/minibuf.c
index bedc5644807..3f34b1b0834 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -187,13 +187,15 @@ zip_minibuffer_stacks (Lisp_Object dest_window, Lisp_Object source_window)
/* If `minibuffer_follows_selected_frame' is t, or we're about to
delete a frame which potentially "contains" minibuffers, move them
- from the old frame to the selected frame. This function is
+ from the old frame to the to-be-selected frame. This function is
intended to be called from `do_switch_frame' in frame.c. OF is the
- old frame, FOR_DELETION is true if OF is about to be deleted. */
+ old frame, FRAME is the to-be-selected frame, and FOR_DELETION is true
+ if OF is about to be deleted. */
void
-move_minibuffers_onto_frame (struct frame *of, bool for_deletion)
+move_minibuffers_onto_frame (struct frame *of, Lisp_Object frame,
+ bool for_deletion)
{
- struct frame *f = XFRAME (selected_frame);
+ struct frame *f = XFRAME (frame);
minibuf_window = f->minibuffer_window;
if (!(minibuf_level
@@ -206,7 +208,7 @@ move_minibuffers_onto_frame (struct frame *of, bool for_deletion)
{
zip_minibuffer_stacks (f->minibuffer_window, of->minibuffer_window);
if (for_deletion && XFRAME (MB_frame) != of)
- MB_frame = selected_frame;
+ MB_frame = frame;
}
}
diff --git a/src/nsmenu.m b/src/nsmenu.m
index ae795a0d22b..b06f737bacf 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -1551,7 +1551,6 @@ pop_down_menu (void *arg)
#ifdef NS_IMPL_COCOA
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
#endif
- discard_menu_items ();
}
}
@@ -1599,6 +1598,7 @@ ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
if (error_name)
{
+ unbind_to (specpdl_count, Qnil);
discard_menu_items ();
[dialog close];
error ("%s", error_name);
@@ -1608,6 +1608,9 @@ ns_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
popup_activated_flag = 1;
tem = [dialog runDialogAt: p];
unbind_to (specpdl_count, Qnil);
+
+ /* This must come *after* unuse_menu_items. */
+ discard_menu_items ();
return tem;
}
diff --git a/src/nsterm.m b/src/nsterm.m
index b8b4e66cd11..1fc72d83f66 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -37,7 +37,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
#include <time.h>
#include <signal.h>
#include <unistd.h>
-#include <stdbool.h>
#include <c-ctype.h>
#include <c-strcase.h>
@@ -2480,7 +2479,7 @@ get_keysym_name (int keysym)
{
static char value[16];
NSTRACE ("get_keysym_name");
- sprintf (value, "%d", keysym);
+ snprintf (value, 16, "%d", keysym);
return value;
}
@@ -3996,6 +3995,7 @@ static void
ns_draw_stretch_glyph_string (struct glyph_string *s)
{
struct face *face;
+ NSColor *fg_color;
if (s->hl == DRAW_CURSOR
&& !x_stretch_cursor_p)
@@ -4092,8 +4092,20 @@ ns_draw_stretch_glyph_string (struct glyph_string *s)
NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
}
}
-}
+ /* Draw overlining, etc. on the stretch glyph (or the part of the
+ stretch glyph after the cursor). If the glyph has a box, then
+ decorations will be drawn after drawing the box in
+ ns_draw_glyph_string, in order to prevent them from being
+ overwritten by the box. */
+ if (s->face->box == FACE_NO_BOX)
+ {
+ fg_color = [NSColor colorWithUnsignedLong:
+ NS_FACE_FOREGROUND (s->face)];
+ ns_draw_text_decoration (s, s->face, fg_color,
+ s->background_width, s->x);
+ }
+}
static void
ns_draw_glyph_string_foreground (struct glyph_string *s)
@@ -4251,7 +4263,7 @@ ns_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
{
unsigned int ch = glyph->u.glyphless.ch;
eassume (ch <= MAX_CHAR);
- sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
+ snprintf (buf, 7, "%0*X", ch < 0x10000 ? 4 : 6, ch);
str = buf;
}
@@ -4411,7 +4423,8 @@ ns_draw_glyph_string (struct glyph_string *s)
{
NSColor *fg_color;
- fg_color = [NSColor colorWithUnsignedLong:NS_FACE_FOREGROUND (s->face)];
+ fg_color = [NSColor colorWithUnsignedLong: NS_FACE_FOREGROUND (s->face)];
+
ns_draw_text_decoration (s, s->face, fg_color,
s->background_width, s->x);
}
@@ -6103,17 +6116,20 @@ ns_term_shutdown (int sig)
- (void) terminate: (id)sender
{
+ struct input_event ie;
+ struct frame *f;
+
NSTRACE ("[EmacsApp terminate:]");
- struct frame *emacsframe = SELECTED_FRAME ();
+ f = SELECTED_FRAME ();
+ EVENT_INIT (ie);
- if (!emacs_event)
- return;
+ ie.kind = NS_NONKEY_EVENT;
+ ie.code = KEY_NS_POWER_OFF;
+ ie.arg = Qt; /* mark as non-key event */
+ XSETFRAME (ie.frame_or_window, f);
- emacs_event->kind = NS_NONKEY_EVENT;
- emacs_event->code = KEY_NS_POWER_OFF;
- emacs_event->arg = Qt; /* mark as non-key event */
- EV_TRAILER ((id)nil);
+ kbd_buffer_store_event (&ie);
}
static bool
@@ -7901,7 +7917,6 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
NSRect r = [win frame];
NSArray *screens = [NSScreen screens];
NSScreen *screen = [screens objectAtIndex: 0];
- struct input_event ie;
NSTRACE ("[EmacsView windowDidMove:]");
@@ -7917,6 +7932,8 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
if (emacs_event)
{
+ struct input_event ie;
+ EVENT_INIT (ie);
ie.kind = MOVE_FRAME_EVENT;
XSETFRAME (ie.frame_or_window, emacsframe);
XSETINT (ie.x, emacsframe->left_pos);
@@ -8579,7 +8596,7 @@ ns_create_font_panel_buttons (id target, SEL select, SEL cancel_action)
EmacsLayer *layer = (EmacsLayer *)[self layer];
[layer setContentsScale:[[notification object] backingScaleFactor]];
- [layer setColorSpace:[[[notification object] colorSpace] CGColorSpace]];
+ [layer setColorSpace:[(id) [[notification object] colorSpace] CGColorSpace]];
ns_clear_frame (emacsframe);
expose_frame (emacsframe, 0, 0, NSWidth (frame), NSHeight (frame));
diff --git a/src/pdumper.c b/src/pdumper.c
index 903298f17d2..5e6ccd9bd88 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2067,7 +2067,7 @@ dump_interval_tree (struct dump_context *ctx,
static dump_off
dump_string (struct dump_context *ctx, const struct Lisp_String *string)
{
-#if CHECK_STRUCTS && !defined (HASH_Lisp_String_C2CAF90352)
+#if CHECK_STRUCTS && !defined (HASH_Lisp_String_03B2DF1C8E)
# error "Lisp_String changed. See CHECK_STRUCTS comment in config.h."
#endif
/* If we have text properties, write them _after_ the string so that
diff --git a/src/sqlite.c b/src/sqlite.c
index 54bfb7b6c61..1526e344e53 100644
--- a/src/sqlite.c
+++ b/src/sqlite.c
@@ -51,6 +51,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_bind_double, (sqlite3_stmt*, int, double));
DEF_DLL_FN (SQLITE_API int, sqlite3_bind_null, (sqlite3_stmt*, int));
DEF_DLL_FN (SQLITE_API int, sqlite3_bind_int, (sqlite3_stmt*, int, int));
DEF_DLL_FN (SQLITE_API const char*, sqlite3_errmsg, (sqlite3*));
+DEF_DLL_FN (SQLITE_API const char*, sqlite3_errstr, (int));
DEF_DLL_FN (SQLITE_API int, sqlite3_step, (sqlite3_stmt*));
DEF_DLL_FN (SQLITE_API int, sqlite3_changes, (sqlite3*));
DEF_DLL_FN (SQLITE_API int, sqlite3_column_count, (sqlite3_stmt*));
@@ -88,6 +89,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
# undef sqlite3_bind_null
# undef sqlite3_bind_int
# undef sqlite3_errmsg
+# undef sqlite3_errstr
# undef sqlite3_step
# undef sqlite3_changes
# undef sqlite3_column_count
@@ -112,6 +114,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
# define sqlite3_bind_null fn_sqlite3_bind_null
# define sqlite3_bind_int fn_sqlite3_bind_int
# define sqlite3_errmsg fn_sqlite3_errmsg
+# define sqlite3_errstr fn_sqlite3_errstr
# define sqlite3_step fn_sqlite3_step
# define sqlite3_changes fn_sqlite3_changes
# define sqlite3_column_count fn_sqlite3_column_count
@@ -139,6 +142,7 @@ load_dll_functions (HMODULE library)
LOAD_DLL_FN (library, sqlite3_bind_null);
LOAD_DLL_FN (library, sqlite3_bind_int);
LOAD_DLL_FN (library, sqlite3_errmsg);
+ LOAD_DLL_FN (library, sqlite3_errstr);
LOAD_DLL_FN (library, sqlite3_step);
LOAD_DLL_FN (library, sqlite3_changes);
LOAD_DLL_FN (library, sqlite3_column_count);
@@ -373,72 +377,6 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values)
return NULL;
}
-DEFUN ("sqlite-execute", Fsqlite_execute, Ssqlite_execute, 2, 3, 0,
- doc: /* Execute a non-select SQL statement.
-If VALUES is non-nil, it should be a vector or a list of values
-to bind when executing a statement like
-
- insert into foo values (?, ?, ...)
-
-Value is the number of affected rows. */)
- (Lisp_Object db, Lisp_Object query, Lisp_Object values)
-{
- check_sqlite (db, false);
- CHECK_STRING (query);
- if (!(NILP (values) || CONSP (values) || VECTORP (values)))
- xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
-
- sqlite3 *sdb = XSQLITE (db)->db;
- Lisp_Object retval = Qnil;
- const char *errmsg = NULL;
- Lisp_Object encoded = encode_string (query);
- sqlite3_stmt *stmt = NULL;
-
- /* We only execute the first statement -- if there's several
- (separated by a semicolon), the subsequent statements won't be
- done. */
- int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL);
- if (ret != SQLITE_OK)
- {
- if (stmt != NULL)
- {
- sqlite3_finalize (stmt);
- sqlite3_reset (stmt);
- }
-
- errmsg = sqlite3_errmsg (sdb);
- goto exit;
- }
-
- /* Bind ? values. */
- if (!NILP (values)) {
- const char *err = bind_values (sdb, stmt, values);
- if (err != NULL)
- {
- errmsg = err;
- goto exit;
- }
- }
-
- ret = sqlite3_step (stmt);
- sqlite3_finalize (stmt);
- if (ret != SQLITE_OK && ret != SQLITE_DONE)
- {
- errmsg = sqlite3_errmsg (sdb);
- goto exit;
- }
-
- retval = make_fixnum (sqlite3_changes (sdb));
-
- exit:
- if (errmsg != NULL)
- xsignal1 (ret == SQLITE_LOCKED || ret == SQLITE_BUSY?
- Qsqlite_locked_error: Qerror,
- build_string (errmsg));
-
- return retval;
-}
-
static Lisp_Object
row_to_value (sqlite3_stmt *stmt)
{
@@ -484,6 +422,94 @@ row_to_value (sqlite3_stmt *stmt)
}
static Lisp_Object
+sqlite_prepare_errmsg (int code, sqlite3 *sdb)
+{
+ Lisp_Object errmsg = build_string (sqlite3_errstr (code));
+ /* More details about what went wrong. */
+ const char *sql_error = sqlite3_errmsg (sdb);
+ if (sql_error)
+ return CALLN (Fformat, build_string ("%s (%s)"),
+ errmsg, build_string (sql_error));
+ else
+ return errmsg;
+}
+
+DEFUN ("sqlite-execute", Fsqlite_execute, Ssqlite_execute, 2, 3, 0,
+ doc: /* Execute a non-select SQL statement.
+If VALUES is non-nil, it should be a vector or a list of values
+to bind when executing a statement like
+
+ insert into foo values (?, ?, ...)
+
+Value is the number of affected rows. */)
+ (Lisp_Object db, Lisp_Object query, Lisp_Object values)
+{
+ check_sqlite (db, false);
+ CHECK_STRING (query);
+ if (!(NILP (values) || CONSP (values) || VECTORP (values)))
+ xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
+
+ sqlite3 *sdb = XSQLITE (db)->db;
+ Lisp_Object errmsg = Qnil,
+ encoded = encode_string (query);
+ sqlite3_stmt *stmt = NULL;
+
+ /* We only execute the first statement -- if there's several
+ (separated by a semicolon), the subsequent statements won't be
+ done. */
+ int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), -1, &stmt, NULL);
+ if (ret != SQLITE_OK)
+ {
+ if (stmt != NULL)
+ {
+ sqlite3_finalize (stmt);
+ sqlite3_reset (stmt);
+ }
+
+ errmsg = sqlite_prepare_errmsg (ret, sdb);
+ goto exit;
+ }
+
+ /* Bind ? values. */
+ if (!NILP (values))
+ {
+ const char *err = bind_values (sdb, stmt, values);
+ if (err != NULL)
+ {
+ errmsg = build_string (err);
+ goto exit;
+ }
+ }
+
+ ret = sqlite3_step (stmt);
+
+ if (ret == SQLITE_ROW)
+ {
+ Lisp_Object data = Qnil;
+ do
+ data = Fcons (row_to_value (stmt), data);
+ while (sqlite3_step (stmt) == SQLITE_ROW);
+
+ sqlite3_finalize (stmt);
+ return Fnreverse (data);
+ }
+ else if (ret == SQLITE_OK || ret == SQLITE_DONE)
+ {
+ Lisp_Object rows = make_fixnum (sqlite3_changes (sdb));
+ sqlite3_finalize (stmt);
+ return rows;
+ }
+ else
+ errmsg = build_string (sqlite3_errmsg (sdb));
+
+ exit:
+ sqlite3_finalize (stmt);
+ xsignal1 (ret == SQLITE_LOCKED || ret == SQLITE_BUSY?
+ Qsqlite_locked_error: Qerror,
+ errmsg);
+}
+
+static Lisp_Object
column_names (sqlite3_stmt *stmt)
{
Lisp_Object columns = Qnil;
@@ -517,9 +543,8 @@ which means that we return a set object that can be queried with
xsignal1 (Qerror, build_string ("VALUES must be a list or a vector"));
sqlite3 *sdb = XSQLITE (db)->db;
- Lisp_Object retval = Qnil;
- const char *errmsg = NULL;
- Lisp_Object encoded = encode_string (query);
+ Lisp_Object retval = Qnil, errmsg = Qnil,
+ encoded = encode_string (query);
sqlite3_stmt *stmt = NULL;
int ret = sqlite3_prepare_v2 (sdb, SSDATA (encoded), SBYTES (encoded),
@@ -528,7 +553,7 @@ which means that we return a set object that can be queried with
{
if (stmt)
sqlite3_finalize (stmt);
-
+ errmsg = sqlite_prepare_errmsg (ret, sdb);
goto exit;
}
@@ -539,7 +564,7 @@ which means that we return a set object that can be queried with
if (err != NULL)
{
sqlite3_finalize (stmt);
- errmsg = err;
+ errmsg = build_string (err);
goto exit;
}
}
@@ -553,7 +578,7 @@ which means that we return a set object that can be queried with
/* Return the data directly. */
Lisp_Object data = Qnil;
- while ((ret = sqlite3_step (stmt)) == SQLITE_ROW)
+ while (sqlite3_step (stmt) == SQLITE_ROW)
data = Fcons (row_to_value (stmt), data);
if (EQ (return_type, Qfull))
@@ -563,8 +588,8 @@ which means that we return a set object that can be queried with
sqlite3_finalize (stmt);
exit:
- if (errmsg != NULL)
- xsignal1 (Qerror, build_string (errmsg));
+ if (! NILP (errmsg))
+ xsignal1 (Qerror, errmsg);
return retval;
}
diff --git a/src/sysdep.c b/src/sysdep.c
index efd9638b07a..736723bdf3d 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1304,7 +1304,10 @@ init_sys_modes (struct tty_display_info *tty_out)
}
#endif /* F_GETOWN */
- setvbuf (tty_out->output, NULL, _IOFBF, BUFSIZ);
+ const size_t buffer_size = (tty_out->output_buffer_size
+ ? tty_out->output_buffer_size
+ : BUFSIZ);
+ setvbuf (tty_out->output, NULL, _IOFBF, buffer_size);
if (tty_out->terminal->set_terminal_modes_hook)
tty_out->terminal->set_terminal_modes_hook (tty_out->terminal);
@@ -2429,7 +2432,7 @@ emacs_pipe (int fd[2])
/* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs.
For the background behind this mess, please see Austin Group defect 529
- <http://austingroupbugs.net/view.php?id=529>. */
+ <https://austingroupbugs.net/view.php?id=529>. */
#ifndef POSIX_CLOSE_RESTART
# define POSIX_CLOSE_RESTART 1
diff --git a/src/systhread.h b/src/systhread.h
index bf4e0306cdc..10d6237f275 100644
--- a/src/systhread.h
+++ b/src/systhread.h
@@ -19,8 +19,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifndef SYSTHREAD_H
#define SYSTHREAD_H
-#include <stdbool.h>
-
#include <attribute.h>
#ifdef THREADS_ENABLED
diff --git a/src/term.c b/src/term.c
index 2e43d89232f..f8104e0304e 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2400,6 +2400,44 @@ frame's terminal). */)
return Qnil;
}
+DEFUN ("tty--set-output-buffer-size", Ftty__set_output_buffer_size,
+ Stty__set_output_buffer_size, 1, 2, 0, doc:
+ /* Set the output buffer size for a TTY.
+
+SIZE zero means use the system's default value. If SIZE is
+non-zero, this also avoids flushing the output stream.
+
+TTY may be a terminal object, a frame, or nil (meaning the selected
+frame's terminal).
+
+This function temporarily suspends and resumes the terminal
+device. */)
+ (Lisp_Object size, Lisp_Object tty)
+{
+ if (!TYPE_RANGED_FIXNUMP (size_t, size))
+ error ("Invalid output buffer size");
+ Fsuspend_tty (tty);
+ struct terminal *terminal = decode_tty_terminal (tty);
+ terminal->display_info.tty->output_buffer_size = XFIXNUM (size);
+ return Fresume_tty (tty);
+}
+
+DEFUN ("tty--output-buffer-size", Ftty__output_buffer_size,
+ Stty__output_buffer_size, 0, 1, 0, doc:
+ /* Return the output buffer size of TTY.
+
+TTY may be a terminal object, a frame, or nil (meaning the selected
+frame's terminal).
+
+A value of zero means TTY uses the system's default value. */)
+ (Lisp_Object tty)
+{
+ struct terminal *terminal = decode_tty_terminal (tty);
+ if (terminal)
+ return make_fixnum (terminal->display_info.tty->output_buffer_size);
+ error ("Not a tty terminal");
+}
+
/***********************************************************************
Mouse
@@ -4556,6 +4594,8 @@ trigger redisplay. */);
defsubr (&Stty_top_frame);
defsubr (&Ssuspend_tty);
defsubr (&Sresume_tty);
+ defsubr (&Stty__set_output_buffer_size);
+ defsubr (&Stty__output_buffer_size);
#ifdef HAVE_GPM
defsubr (&Sgpm_mouse_start);
defsubr (&Sgpm_mouse_stop);
diff --git a/src/termchar.h b/src/termchar.h
index 49560dbc2ad..0f172464113 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -53,6 +53,11 @@ struct tty_display_info
FILE *output; /* The stream to be used for terminal output.
NULL if the terminal is suspended. */
+ /* Size of output buffer. A value of zero means use the default of
+ BUFIZE. If non-zero, also minimize writes to the tty by avoiding
+ calls to flush. */
+ size_t output_buffer_size;
+
FILE *termscript; /* If nonzero, send all terminal output
characters to this stream also. */
diff --git a/src/textprop.c b/src/textprop.c
index c91a2b729c6..c22b579af22 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -2389,15 +2389,7 @@ returned. */);
DEFVAR_LISP ("inhibit-point-motion-hooks", Vinhibit_point_motion_hooks,
doc: /* If non-nil, don't run `point-left' and `point-entered' text properties.
-This also inhibits the use of the `intangible' text property.
-
-This variable is obsolete since Emacs-25.1. Use `cursor-intangible-mode'
-or `cursor-sensor-mode' instead. */);
- /* FIXME: We should make-obsolete-variable, but that signals too many
- warnings in code which does (let ((inhibit-point-motion-hooks t)) ...)
- Ideally, make-obsolete-variable should let us specify that only the nil
- value is obsolete, but that requires too many changes in bytecomp.el,
- so for now we'll keep it "obsolete via the docstring". */
+This also inhibits the use of the `intangible' text property. */);
Vinhibit_point_motion_hooks = Qt;
DEFVAR_LISP ("text-property-default-nonsticky",
diff --git a/src/w32fns.c b/src/w32fns.c
index 745458d0a03..5f652ae9e46 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -10447,6 +10447,66 @@ w32_get_resource (const char *key, const char *name, LPDWORD lpdwtype)
return (NULL);
}
+#ifdef WINDOWSNT
+
+/***********************************************************************
+ Wallpaper
+ ***********************************************************************/
+
+typedef BOOL (WINAPI * SystemParametersInfoW_Proc) (UINT,UINT,PVOID,UINT);
+SystemParametersInfoW_Proc system_parameters_info_w_fn = NULL;
+
+DEFUN ("w32-set-wallpaper", Fw32_set_wallpaper, Sw32_set_wallpaper, 1, 1, 0,
+ doc: /* Set the desktop wallpaper image to IMAGE-FILE. */)
+ (Lisp_Object image_file)
+{
+ Lisp_Object encoded = ENCODE_FILE (Fexpand_file_name (image_file, Qnil));
+ char *fname = SSDATA (encoded);
+ BOOL result = false;
+ DWORD err = 0;
+
+ /* UNICOWS.DLL seems to have SystemParametersInfoW, but it doesn't
+ seem to be worth the hassle to support that on Windows 9X for the
+ benefit of this minor feature. Let them use on Windows 9X only
+ image file names that can be encoded by the system codepage. */
+ if (w32_unicode_filenames && system_parameters_info_w_fn)
+ {
+ wchar_t fname_w[MAX_PATH];
+
+ if (filename_to_utf16 (fname, fname_w) != 0)
+ err = ERROR_FILE_NOT_FOUND;
+ else
+ result = SystemParametersInfoW (SPI_SETDESKWALLPAPER, 0, fname_w,
+ SPIF_SENDCHANGE);
+ }
+ else
+ {
+ char fname_a[MAX_PATH];
+
+ if (filename_to_ansi (fname, fname_a) != 0)
+ err = ERROR_FILE_NOT_FOUND;
+ else
+ result = SystemParametersInfoA (SPI_SETDESKWALLPAPER, 0, fname_a,
+ SPIF_SENDCHANGE);
+ }
+ if (!result)
+ {
+ if (err == ERROR_FILE_NOT_FOUND)
+ error ("Wallpaper file %s does not exist or cannot be accessed", fname);
+ else
+ {
+ err = GetLastError ();
+ if (err)
+ error ("Could not set desktop wallpaper: %s", w32_strerror (err));
+ else
+ error ("Could not set desktop wallpaper (wrong image type?)");
+ }
+ }
+
+ return Qnil;
+}
+#endif
+
/***********************************************************************
Initialization
***********************************************************************/
@@ -10926,6 +10986,7 @@ keys when IME input is received. */);
defsubr (&Sx_file_dialog);
#ifdef WINDOWSNT
defsubr (&Ssystem_move_file_to_trash);
+ defsubr (&Sw32_set_wallpaper);
#endif
}
@@ -11179,6 +11240,10 @@ globals_of_w32fns (void)
get_proc_addr (user32_lib, "EnumDisplayMonitors");
get_title_bar_info_fn = (GetTitleBarInfo_Proc)
get_proc_addr (user32_lib, "GetTitleBarInfo");
+#ifndef CYGWIN
+ system_parameters_info_w_fn = (SystemParametersInfoW_Proc)
+ get_proc_addr (user32_lib, "SystemParametersInfoW");
+#endif
{
HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
diff --git a/src/widget.c b/src/widget.c
index 5a75cdaca8e..aaab33b6d8e 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -195,7 +195,7 @@ round_size_to_char (EmacsFrame ew, Dimension in_width, Dimension in_height,
out_width, out_height);
}
-static Widget
+static WMShellWidget
get_wm_shell (Widget w)
{
Widget wmshell;
@@ -204,7 +204,7 @@ get_wm_shell (Widget w)
wmshell && !XtIsWMShell (wmshell);
wmshell = XtParent (wmshell));
- return wmshell;
+ return (WMShellWidget) wmshell;
}
#if 0 /* Currently not used. */
@@ -269,8 +269,8 @@ set_frame_size (EmacsFrame ew)
(f, build_string ("set_frame_size"));
}
-static void
-update_wm_hints (Widget wmshell, EmacsFrame ew)
+static bool
+update_wm_hints (WMShellWidget wmshell, EmacsFrame ew)
{
int cw;
int ch;
@@ -280,6 +280,12 @@ update_wm_hints (Widget wmshell, EmacsFrame ew)
int char_height;
int base_width;
int base_height;
+ char buffer[sizeof wmshell->wm.size_hints];
+ char *hints_ptr;
+
+ /* Copy the old size hints to the buffer. */
+ memcpy (buffer, &wmshell->wm.size_hints,
+ sizeof wmshell->wm.size_hints);
pixel_to_char_size (ew, ew->core.width, ew->core.height,
&char_width, &char_height);
@@ -292,27 +298,29 @@ update_wm_hints (Widget wmshell, EmacsFrame ew)
base_height = (wmshell->core.height - ew->core.height
+ (rounded_height - (char_height * ch)));
- /* Ensure that Xt actually sets window manager hint flags specified
- by the caller by making sure XtNminWidth (a relatively harmless
- resource) always changes each time this function is invoked. */
- ew->emacs_frame.size_switch = !ew->emacs_frame.size_switch;
-
- XtVaSetValues (wmshell,
+ XtVaSetValues ((Widget) wmshell,
XtNbaseWidth, (XtArgVal) base_width,
XtNbaseHeight, (XtArgVal) base_height,
XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw),
XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch),
- XtNminWidth, (XtArgVal) (base_width
- + ew->emacs_frame.size_switch),
- XtNminHeight, (XtArgVal) (base_height
- + ew->emacs_frame.size_switch),
+ XtNminWidth, (XtArgVal) base_width,
+ XtNminHeight, (XtArgVal) base_height,
NULL);
+
+ /* Return if size hints really changed. If they did not, then Xt
+ probably didn't set them either (or take the flags into
+ account.) */
+ hints_ptr = (char *) &wmshell->wm.size_hints;
+
+ /* Skip flags, which is unsigned long. */
+ return memcmp (hints_ptr + sizeof (long), buffer + sizeof (long),
+ sizeof wmshell->wm.wm_hints - sizeof (long));
}
-void
+bool
widget_update_wm_size_hints (Widget widget, Widget frame)
{
- update_wm_hints (widget, (EmacsFrame) frame);
+ return update_wm_hints ((WMShellWidget) widget, (EmacsFrame) frame);
}
static void
@@ -357,8 +365,6 @@ EmacsFrameInitialize (Widget request, Widget new,
exit (1);
}
- ew->emacs_frame.size_switch = 1;
-
update_from_various_frame_slots (ew);
set_frame_size (ew);
}
diff --git a/src/widget.h b/src/widget.h
index 2906d5ff9ec..cf83cb10781 100644
--- a/src/widget.h
+++ b/src/widget.h
@@ -97,6 +97,6 @@ extern struct _DisplayContext *display_context;
/* Special entry points */
void EmacsFrameSetCharSize (Widget, int, int);
void widget_store_internal_border (Widget widget);
-void widget_update_wm_size_hints (Widget widget, Widget frame);
+bool widget_update_wm_size_hints (Widget widget, Widget frame);
#endif /* _EmacsFrame_h */
diff --git a/src/widgetprv.h b/src/widgetprv.h
index fe960326b03..3a4d9206ffe 100644
--- a/src/widgetprv.h
+++ b/src/widgetprv.h
@@ -49,9 +49,6 @@ typedef struct {
Boolean visual_bell; /* flash instead of beep */
int bell_volume; /* how loud is beep */
- int size_switch; /* hack to make setting size
- hints work correctly */
-
/* private state */
} EmacsFramePart;
diff --git a/src/window.c b/src/window.c
index 12a212a85ac..4e8b352e164 100644
--- a/src/window.c
+++ b/src/window.c
@@ -52,6 +52,7 @@ static ptrdiff_t get_leaf_windows (struct window *, struct window **,
ptrdiff_t);
static void window_scroll_pixel_based (Lisp_Object, int, bool, bool);
static void window_scroll_line_based (Lisp_Object, int, bool, bool);
+static void window_scroll_for_long_lines (struct window *, int, bool);
static void foreach_window (struct frame *,
bool (* fn) (struct window *, void *),
void *);
@@ -5536,19 +5537,40 @@ window_internal_height (struct window *w)
static void
window_scroll (Lisp_Object window, EMACS_INT n, bool whole, bool noerror)
{
+ struct window *w = XWINDOW (window);
+ struct buffer *b = XBUFFER (w->contents);
+ bool long_lines_truncated =
+ b->long_line_optimizations_p && !NILP (BVAR (b, truncate_lines));
specpdl_ref count = SPECPDL_INDEX ();
n = clip_to_bounds (INT_MIN, n, INT_MAX);
- wset_redisplay (XWINDOW (window));
+ wset_redisplay (w);
- if (whole && fast_but_imprecise_scrolling)
+ /* Does this window's buffer have very long and truncated lines? */
+ if (b->long_line_optimizations_p
+ && !long_lines_truncated
+ && !NILP (Vtruncate_partial_width_windows)
+ && w->total_cols < FRAME_COLS (XFRAME (WINDOW_FRAME (w))))
+ {
+ if (FIXNUMP (Vtruncate_partial_width_windows))
+ long_lines_truncated =
+ w->total_cols < XFIXNAT (Vtruncate_partial_width_windows);
+ else
+ long_lines_truncated = true;
+ }
+
+ if (whole && (fast_but_imprecise_scrolling || long_lines_truncated))
specbind (Qfontification_functions, Qnil);
- /* On GUI frames, use the pixel-based version which is much slower
- than the line-based one but can handle varying line heights. */
- if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
+ if (whole && long_lines_truncated)
+ window_scroll_for_long_lines (w, n, noerror);
+ else if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
{
+
+ /* On GUI frames, use the pixel-based version which is much
+ slower than the line-based one, but can handle varying
+ line heights. */
record_unwind_protect_void (unwind_display_working_on_window);
display_working_on_window_p = true;
window_scroll_pixel_based (window, n, whole, noerror);
@@ -5598,6 +5620,71 @@ sanitize_next_screen_context_lines (void)
return clip_to_bounds (0, next_screen_context_lines, 1000000);
}
+/* Implementation of window_scroll for very long and truncated lines.
+ This is a simplified version, it only handles WHOLE window scrolls,
+ and doesn't honor scroll-preserve-screen-position nor scroll-margin. */
+static void
+window_scroll_for_long_lines (struct window *w, int n, bool noerror)
+{
+ ptrdiff_t startpos = marker_position (w->start);
+ ptrdiff_t startbyte = marker_byte_position (w->start);
+ int nscls = sanitize_next_screen_context_lines ();
+ register int ht = window_internal_height (w);
+
+ n *= max (1, ht - nscls);
+
+ /* If point is not visible in window, bring it inside window. */
+ struct position pos;
+ int rtop, rbot, dummy_rowh, dummy_vpos, dummy_x, dummy_y;
+ if (!(PT >= startpos
+ && PT <= ZV
+ && startpos <= ZV
+ && pos_visible_p (w, PT, &dummy_x, &dummy_y, &rtop, &rbot, &dummy_rowh,
+ &dummy_vpos)
+ && !rtop && !rbot))
+ {
+ pos = *vmotion (PT, PT_BYTE, - (ht / 2), w);
+ startpos = pos.bufpos;
+ startbyte = pos.bytepos;
+ }
+ SET_PT_BOTH (startpos, startbyte);
+
+ bool lose = n < 0 && PT == BEGV;
+ pos = *vmotion (PT, PT_BYTE, n, w);
+ if (lose)
+ {
+ if (noerror)
+ return;
+ else
+ xsignal0 (Qbeginning_of_buffer);
+ }
+
+ bool bolp = pos.bufpos == BEGV || FETCH_BYTE (pos.bytepos - 1) == '\n';
+ if (pos.bufpos < ZV)
+ {
+ set_marker_restricted_both (w->start, w->contents,
+ pos.bufpos, pos.bytepos);
+ w->start_at_line_beg = bolp;
+ wset_update_mode_line (w);
+ /* Set force_start so that redisplay_window will run
+ the window-scroll-functions. */
+ w->force_start = true;
+ SET_PT_BOTH (pos.bufpos, pos.bytepos);
+ if (n > 0)
+ pos = *vmotion (PT, PT_BYTE, ht / 2, w);
+ else if (n < 0)
+ pos = *vmotion (PT, PT_BYTE, - (ht / 2), w);
+ SET_PT_BOTH (pos.bufpos, pos.bytepos);
+ }
+ else
+ {
+ if (noerror)
+ return;
+ else
+ xsignal0 (Qend_of_buffer);
+ }
+}
+
/* Implementation of window_scroll that works based on pixel line
heights. See the comment of window_scroll for parameter
descriptions. */
@@ -8213,6 +8300,8 @@ init_window_once (void)
minibuf_selected_window = Qnil;
staticpro (&minibuf_selected_window);
+ old_selected_window = Qnil;
+ staticpro (&old_selected_window);
pdumper_do_now_and_after_late_load (init_window_once_for_pdumper);
}
diff --git a/src/xdisp.c b/src/xdisp.c
index 80a07636951..e390de6a336 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -1960,15 +1960,18 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
int top_x_before_string = it3.current_x;
/* Finally, advance the iterator until we hit the
first display element whose character position is
- CHARPOS, or until the first newline from the
- display string, which signals the end of the
- display line. */
+ at or beyond CHARPOS, or until the first newline
+ from the display string, which signals the end of
+ the display line. */
while (get_next_display_element (&it3))
{
if (!EQ (it3.object, string))
top_x_before_string = it3.current_x;
PRODUCE_GLYPHS (&it3);
- if (IT_CHARPOS (it3) == charpos
+ if ((it3.bidi_it.scan_dir == 1
+ && IT_CHARPOS (it3) >= charpos)
+ || (it3.bidi_it.scan_dir == -1
+ && IT_CHARPOS (it3) <= charpos)
|| ITERATOR_AT_END_OF_LINE_P (&it3))
break;
it3_moved = true;
@@ -6309,7 +6312,10 @@ handle_composition_prop (struct it *it)
pos_byte = IT_STRING_BYTEPOS (*it);
string = it->string;
s = SDATA (string) + pos_byte;
- it->c = STRING_CHAR (s);
+ if (STRING_MULTIBYTE (string))
+ it->c = STRING_CHAR (s);
+ else
+ it->c = *s;
}
else
{
@@ -7040,7 +7046,14 @@ pop_it (struct it *it)
|| (STRINGP (it->object)
&& IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
&& IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
- || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
+ || (CONSP (it->object) && it->method == GET_FROM_STRETCH)
+ /* We could be in the middle of handling a list or a
+ vector of several 'display' properties, in which
+ case we should only verify the above conditions when
+ we pop the iterator stack the last time, because
+ higher stack levels cannot "iterate out of the
+ display property". */
+ || it->sp > 0);
}
/* If we move the iterator over text covered by a display property
to a new buffer position, any info about previously seen overlays
@@ -10710,11 +10723,6 @@ move_it_vertically_backward (struct it *it, int dy)
while (nlines-- && IT_CHARPOS (*it) > pos_limit)
back_to_previous_visible_line_start (it);
- /* Move one line more back, for the (rare) situation where we have
- bidi-reordered continued lines, and we start from the top-most
- screen line, which is the last in logical order. */
- if (it->bidi_p && dy == 0)
- back_to_previous_visible_line_start (it);
/* Reseat the iterator here. When moving backward, we don't want
reseat to skip forward over invisible text, set up the iterator
to deliver from overlay strings at the new position etc. So,
@@ -10956,7 +10964,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
{
struct it it2;
void *it2data = NULL;
- ptrdiff_t start_charpos, i;
+ ptrdiff_t start_charpos, orig_charpos, i;
int nchars_per_row
= (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
bool hit_pos_limit = false;
@@ -10966,7 +10974,7 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
position. This may actually move vertically backwards,
in case of overlays, so adjust dvpos accordingly. */
dvpos += it->vpos;
- start_charpos = IT_CHARPOS (*it);
+ orig_charpos = IT_CHARPOS (*it);
move_it_vertically_backward (it, 0);
dvpos -= it->vpos;
@@ -11019,8 +11027,9 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
RESTORE_IT (&it2, &it2, it2data);
SAVE_IT (it2, *it, it2data);
move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
- /* Move back again if we got too far ahead. */
- if (it->vpos - it2.vpos > delta)
+ /* Move back again if we got too far ahead,
+ or didn't move at all. */
+ if (it->vpos - it2.vpos > delta || IT_CHARPOS (*it) == orig_charpos)
RESTORE_IT (it, &it2, it2data);
else
bidi_unshelve_cache (it2data, true);
@@ -20156,7 +20165,20 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
from point. */
centering_position = window_box_height (w) / 2;
}
- move_it_vertically_backward (&it, centering_position);
+ if (current_buffer->long_line_optimizations_p
+ && it.line_wrap == TRUNCATE)
+ {
+ /* For very long and truncated lines, go back using a simplified
+ method, which ignored any inaccuracies due to line-height
+ differences, display properties/overlays, etc. */
+ int nlines = centering_position / frame_line_height;
+
+ while (nlines-- && IT_CHARPOS (it) > BEGV)
+ back_to_previous_visible_line_start (&it);
+ reseat_1 (&it, it.current.pos, true);
+ }
+ else
+ move_it_vertically_backward (&it, centering_position);
eassert (IT_CHARPOS (it) >= BEGV);
diff --git a/src/xfns.c b/src/xfns.c
index ecb869bf360..91124488994 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3354,22 +3354,30 @@ struct x_xim_text_conversion_data
{
struct coding_system *coding;
char *source;
+ struct x_display_info *dpyinfo;
};
static Lisp_Object
-x_xim_text_to_utf8_unix_1 (ptrdiff_t nargs,
- Lisp_Object *args)
+x_xim_text_to_utf8_unix_1 (ptrdiff_t nargs, Lisp_Object *args)
{
struct x_xim_text_conversion_data *data;
ptrdiff_t nbytes;
+ Lisp_Object coding_system;
data = xmint_pointer (args[0]);
+
+ if (SYMBOLP (Vx_input_coding_system))
+ coding_system = Vx_input_coding_system;
+ else if (!NILP (data->dpyinfo->xim_coding))
+ coding_system = data->dpyinfo->xim_coding;
+ else
+ coding_system = Vlocale_coding_system;
+
nbytes = strlen (data->source);
data->coding->destination = NULL;
- setup_coding_system (Vlocale_coding_system,
- data->coding);
+ setup_coding_system (coding_system, data->coding);
data->coding->mode |= (CODING_MODE_LAST_BLOCK
| CODING_MODE_SAFE_ENCODING);
data->coding->source = (const unsigned char *) data->source;
@@ -3382,8 +3390,7 @@ x_xim_text_to_utf8_unix_1 (ptrdiff_t nargs,
}
static Lisp_Object
-x_xim_text_to_utf8_unix_2 (Lisp_Object val,
- ptrdiff_t nargs,
+x_xim_text_to_utf8_unix_2 (Lisp_Object val, ptrdiff_t nargs,
Lisp_Object *args)
{
struct x_xim_text_conversion_data *data;
@@ -3400,7 +3407,8 @@ x_xim_text_to_utf8_unix_2 (Lisp_Object val,
/* The string returned is not null-terminated. */
static char *
-x_xim_text_to_utf8_unix (XIMText *text, ptrdiff_t *length)
+x_xim_text_to_utf8_unix (struct x_display_info *dpyinfo,
+ XIMText *text, ptrdiff_t *length)
{
unsigned char *wchar_buf;
ptrdiff_t wchar_actual_length, i;
@@ -3424,6 +3432,7 @@ x_xim_text_to_utf8_unix (XIMText *text, ptrdiff_t *length)
data.coding = &coding;
data.source = text->string.multi_byte;
+ data.dpyinfo = dpyinfo;
was_waiting_for_input_p = waiting_for_input;
/* Otherwise Fsignal will crash. */
@@ -3441,18 +3450,21 @@ static void
xic_preedit_draw_callback (XIC xic, XPointer client_data,
XIMPreeditDrawCallbackStruct *call_data)
{
- struct frame *f = x_xic_to_frame (xic);
+ struct frame *f;
struct x_output *output;
- ptrdiff_t text_length = 0;
+ ptrdiff_t text_length;
ptrdiff_t charpos;
ptrdiff_t original_size;
char *text;
char *chg_start, *chg_end;
struct input_event ie;
+
+ f = x_xic_to_frame (xic);
EVENT_INIT (ie);
if (f)
{
+ text_length = 0;
output = FRAME_X_OUTPUT (f);
if (!output->preedit_active)
@@ -3460,7 +3472,8 @@ xic_preedit_draw_callback (XIC xic, XPointer client_data,
if (call_data->text)
{
- text = x_xim_text_to_utf8_unix (call_data->text, &text_length);
+ text = x_xim_text_to_utf8_unix (FRAME_DISPLAY_INFO (f),
+ call_data->text, &text_length);
if (!text)
/* Decoding the IM text failed. */
@@ -4166,11 +4179,15 @@ x_window (struct frame *f)
{
/* XIM server might require some X events. */
unsigned long fevent = NoEventMask;
- XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
- attributes.event_mask |= fevent;
- attribute_mask = CWEventMask;
- XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- attribute_mask, &attributes);
+
+ if (fevent)
+ {
+ XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
+ attributes.event_mask |= fevent;
+ attribute_mask = CWEventMask;
+ XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ attribute_mask, &attributes);
+ }
}
}
#endif /* HAVE_X_I18N */
@@ -5540,15 +5557,15 @@ On MS Windows, this returns nothing useful. */)
switch (DoesBackingStore (dpyinfo->screen))
{
case Always:
- result = intern ("always");
+ result = Qalways;
break;
case WhenMapped:
- result = intern ("when-mapped");
+ result = Qwhen_mapped;
break;
case NotUseful:
- result = intern ("not-useful");
+ result = Qnot_useful;
break;
default:
@@ -5577,22 +5594,22 @@ If omitted or nil, that stands for the selected frame's display.
switch (dpyinfo->visual_info.class)
{
case StaticGray:
- result = intern ("static-gray");
+ result = Qstatic_gray;
break;
case GrayScale:
- result = intern ("gray-scale");
+ result = Qgray_scale;
break;
case StaticColor:
- result = intern ("static-color");
+ result = Qstatic_color;
break;
case PseudoColor:
- result = intern ("pseudo-color");
+ result = Qpseudo_color;
break;
case TrueColor:
- result = intern ("true-color");
+ result = Qtrue_color;
break;
case DirectColor:
- result = intern ("direct-color");
+ result = Qdirect_color;
break;
default:
error ("Display has an unknown visual class");
@@ -6244,8 +6261,8 @@ In addition to the standard attribute keys listed in
the attributes:
source -- String describing the source from which multi-monitor
- information is obtained, one of \"Gdk\", \"XRandr\",
- \"Xinerama\", or \"fallback\"
+ information is obtained, one of \"Gdk\", \"XRandR 1.5\",
+ \"XRandr\", \"Xinerama\", or \"fallback\"
Internal use only, use `display-monitor-attributes-list' instead. */)
(Lisp_Object terminal)
@@ -7711,17 +7728,40 @@ DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
doc: /* Value is the value of window property PROP on FRAME.
If FRAME is nil or omitted, use the selected frame.
-On X Windows, the following optional arguments are also accepted:
-If TYPE is nil or omitted, get the property as a string.
- Otherwise TYPE is the name of the atom that denotes the expected type.
+On X Windows, the following optional arguments are also accepted: If
+TYPE is nil or omitted, get the property as a string. Otherwise TYPE
+is the name of the atom that denotes the expected type.
+
+If TYPE is the string "AnyPropertyType", decode and return the data
+regardless of what the type really is.
+
+The format of the data returned is the same as a selection conversion
+to the given type. For example, if `x-get-selection-internal' returns
+an integer when the selection data is a given type,
+`x-window-property' will do the same for that type.
+
If WINDOW-ID is non-nil, get the property of that window instead of
- FRAME's X window; the number 0 denotes the root window. This argument
- is separate from FRAME because window IDs are not unique across X
- displays or screens on the same display, so FRAME provides context
- for the window ID.
+FRAME's X window; the number 0 denotes the root window. This argument
+is separate from FRAME because window IDs are not unique across X
+displays, so FRAME provides context for the window ID.
+
If DELETE-P is non-nil, delete the property after retrieving it.
If VECTOR-RET-P is non-nil, return a vector of values instead of a string.
+X allows an arbitrary number of properties to be set on any window.
+However, properties are most often set by the window manager or other
+programs on the root window or FRAME's X window in order to
+communicate information to Emacs and other programs. Most of these
+properties are specified as part of the Extended Window Manager Hints
+and the Inter-Client Communication Conventions Manual, which are
+located here:
+
+ https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html
+
+and
+
+ https://x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html
+
Return value is nil if FRAME doesn't have a property with name PROP or
if PROP has no value of TYPE (always a string in the MS Windows case). */)
(Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
@@ -8309,9 +8349,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
disptype = Qmono;
else if (FRAME_X_VISUAL_INFO (f)->class == GrayScale
|| FRAME_X_VISUAL_INFO (f)->class == StaticGray)
- disptype = intern ("grayscale");
+ disptype = Qgrayscale;
else
- disptype = intern ("color");
+ disptype = Qcolor;
if (NILP (Fframe_parameter (frame, Qdisplay_type)))
{
@@ -8973,8 +9013,8 @@ Text larger than the specified size is clipped. */)
start_timer:
/* Let the tip disappear after timeout seconds. */
- tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
- intern ("x-hide-tip"));
+ tip_timer = call3 (Qrun_at_time, timeout, Qnil,
+ Qx_hide_tip);
return unbind_to (count, Qnil);
}
@@ -10072,6 +10112,23 @@ eliminated in future versions of Emacs. */);
/* Tell Emacs about this window system. */
Fprovide (Qx, Qnil);
+ /* Used by Fx_show_tip. */
+ DEFSYM (Qrun_at_time, "run-at-time");
+ DEFSYM (Qx_hide_tip, "x-hide-tip");
+
+ /* Used by display class and backing store reporting functions. */
+ DEFSYM (Qalways, "always");
+ DEFSYM (Qwhen_mapped, "when-mapped");
+ DEFSYM (Qnot_useful, "not-useful");
+ DEFSYM (Qstatic_gray, "static-gray");
+ DEFSYM (Qgray_scale, "gray-scale");
+ DEFSYM (Qstatic_color, "static-color");
+ DEFSYM (Qpseudo_color, "pseudo-color");
+ DEFSYM (Qtrue_color, "true-color");
+ DEFSYM (Qdirect_color, "direct-color");
+ DEFSYM (Qgrayscale, "grayscale");
+ DEFSYM (Qcolor, "color");
+
#ifdef HAVE_XINPUT2
DEFSYM (Qxinput2, "xinput2");
diff --git a/src/xfont.c b/src/xfont.c
index 74237e8aa88..951446b44d2 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -253,9 +253,9 @@ xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
/* Two special cases to avoid opening rather big fonts. */
if (EQ (AREF (props, 2), Qja))
- return list2 (intern ("kana"), intern ("han"));
+ return list2 (Qkana, Qhan);
if (EQ (AREF (props, 2), Qko))
- return list1 (intern ("hangul"));
+ return list1 (Qhangul);
scripts = Fgethash (props, xfont_scripts_cache, Qt);
if (EQ (scripts, Qt))
{
@@ -1130,19 +1130,19 @@ static void syms_of_xfont_for_pdumper (void);
struct font_driver const xfont_driver =
{
- .type = LISPSYM_INITIALLY (Qx),
- .get_cache = xfont_get_cache,
- .list = xfont_list,
- .match = xfont_match,
- .list_family = xfont_list_family,
- .open_font = xfont_open,
- .close_font = xfont_close,
- .prepare_face = xfont_prepare_face,
- .has_char = xfont_has_char,
- .encode_char = xfont_encode_char,
- .text_extents = xfont_text_extents,
- .draw = xfont_draw,
- .check = xfont_check,
+ .type = LISPSYM_INITIALLY (Qx),
+ .get_cache = xfont_get_cache,
+ .list = xfont_list,
+ .match = xfont_match,
+ .list_family = xfont_list_family,
+ .open_font = xfont_open,
+ .close_font = xfont_close,
+ .prepare_face = xfont_prepare_face,
+ .has_char = xfont_has_char,
+ .encode_char = xfont_encode_char,
+ .text_extents = xfont_text_extents,
+ .draw = xfont_draw,
+ .check = xfont_check,
};
void
@@ -1153,6 +1153,10 @@ syms_of_xfont (void)
staticpro (&xfont_scratch_props);
xfont_scratch_props = make_nil_vector (8);
pdumper_do_now_and_after_load (syms_of_xfont_for_pdumper);
+
+ DEFSYM (Qkana, "kana");
+ DEFSYM (Qhan, "han");
+ DEFSYM (Qhangul, "hangul");
}
static void
diff --git a/src/xsettings.c b/src/xsettings.c
index 9c60ff825a4..e4a9865d686 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -1225,7 +1225,8 @@ xsettings_get_font_options (void)
DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
Sfont_get_system_normal_font,
0, 0, 0,
- doc: /* Get the system default application font. */)
+ doc: /* Get the system default application font.
+The font is returned as either a font-spec or font name. */)
(void)
{
return current_font ? build_string (current_font) : Qnil;
@@ -1233,7 +1234,8 @@ DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
DEFUN ("font-get-system-font", Ffont_get_system_font, Sfont_get_system_font,
0, 0, 0,
- doc: /* Get the system default fixed width font. */)
+ doc: /* Get the system default fixed width font.
+The font is returned as either a font-spec or font name. */)
(void)
{
return current_mono_font ? build_string (current_mono_font) : Qnil;
@@ -1282,6 +1284,10 @@ syms_of_xsettings (void)
DEFSYM (Qmonospace_font_name, "monospace-font-name");
DEFSYM (Qfont_name, "font-name");
DEFSYM (Qfont_render, "font-render");
+ DEFSYM (Qdynamic_setting, "dynamic-setting");
+ DEFSYM (Qfont_render_setting, "font-render-setting");
+ DEFSYM (Qsystem_font_setting, "system-font-setting");
+
defsubr (&Sfont_get_system_font);
defsubr (&Sfont_get_system_normal_font);
@@ -1297,9 +1303,9 @@ If this variable is nil, Emacs ignores system font changes. */);
Vxft_settings = empty_unibyte_string;
#if defined USE_CAIRO || defined HAVE_XFT
- Fprovide (intern_c_string ("font-render-setting"), Qnil);
+ Fprovide (Qfont_render_setting, Qnil);
#if defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
- Fprovide (intern_c_string ("system-font-setting"), Qnil);
+ Fprovide (Qsystem_font_setting, Qnil);
#endif
#endif
@@ -1307,5 +1313,5 @@ If this variable is nil, Emacs ignores system font changes. */);
DEFSYM (Qtool_bar_style, "tool-bar-style");
defsubr (&Stool_bar_get_system_style);
- Fprovide (intern_c_string ("dynamic-setting"), Qnil);
+ Fprovide (Qdynamic_setting, Qnil);
}
diff --git a/src/xsmfns.c b/src/xsmfns.c
index 7015a8eb633..7a17e6dbd86 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -511,7 +511,7 @@ Do not call this function yourself. */)
this at the wrong time. */
if (doing_interact && ! kill_emacs)
{
- bool cancel_shutdown = ! NILP (call0 (intern ("emacs-session-save")));
+ bool cancel_shutdown = ! NILP (call0 (Qemacs_session_save));
SmcInteractDone (smc_conn, cancel_shutdown);
SmcSaveYourselfDone (smc_conn, True);
@@ -542,6 +542,8 @@ Do not call this function yourself. */)
void
syms_of_xsmfns (void)
{
+ DEFSYM (Qemacs_session_save, "emacs-session-save");
+
DEFVAR_LISP ("x-session-id", Vx_session_id,
doc: /* The session id Emacs got from the session manager for this session.
Changing the value does not change the session id used by Emacs.
diff --git a/src/xterm.c b/src/xterm.c
index 48502f12d8d..d35af7a8de2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -970,8 +970,8 @@ static const struct x_atom_ref x_atom_refs[] =
/* Ghostscript support. */
ATOM_REFS_INIT ("DONE", Xatom_DONE)
ATOM_REFS_INIT ("PAGE", Xatom_PAGE)
- ATOM_REFS_INIT ("SCROLLBAR", Xatom_Scrollbar)
- ATOM_REFS_INIT ("HORIZONTAL_SCROLLBAR", Xatom_Horizontal_Scrollbar)
+ ATOM_REFS_INIT ("_EMACS_SCROLLBAR", Xatom_Scrollbar)
+ ATOM_REFS_INIT ("_EMACS_HORIZONTAL_SCROLLBAR", Xatom_Horizontal_Scrollbar)
ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED)
/* EWMH */
ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state)
@@ -1143,6 +1143,7 @@ static Window x_get_window_below (Display *, Window, int, int, int *, int *);
#ifndef USE_TOOLKIT_SCROLL_BARS
static void x_scroll_bar_redraw (struct scroll_bar *);
#endif
+static void x_translate_coordinates (struct frame *, int, int, int *, int *);
/* Global state maintained during a drag-and-drop operation. */
@@ -1424,9 +1425,6 @@ struct x_client_list_window
/* The width and height of the window. */
int width, height;
- /* Whether or not the window is mapped. */
- bool mapped_p;
-
/* A bitmask describing events Emacs was listening for from the
window before some extra events were added in
`x_dnd_compute_toplevels'. */
@@ -1438,9 +1436,6 @@ struct x_client_list_window
/* The next window in this list. */
struct x_client_list_window *next;
- /* The Motif protocol style of this window, if any. */
- uint8_t xm_protocol_style;
-
/* The extents of the frame window in each direction. */
int frame_extents_left;
int frame_extents_right;
@@ -1451,18 +1446,24 @@ struct x_client_list_window
/* The border width of this window. */
int border_width;
- /* The rectangles making up the input shape. */
- XRectangle *input_rects;
-
/* The number of rectangles composing the input shape. */
int n_input_rects;
+ /* The rectangles making up the input shape. */
+ XRectangle *input_rects;
+
/* The rectangles making up the bounding shape. */
XRectangle *bounding_rects;
/* The number of rectangles composing the bounding shape. */
int n_bounding_rects;
#endif
+
+ /* The Motif protocol style of this window, if any. */
+ uint8_t xm_protocol_style;
+
+ /* Whether or not the window is mapped. */
+ bool mapped_p;
};
/* List of all toplevels in stacking order, from top to bottom. */
@@ -4852,16 +4853,13 @@ x_dnd_note_self_position (struct x_display_info *dpyinfo, Window target,
{
struct frame *f;
int dest_x, dest_y;
- Window child_return;
f = x_top_window_to_frame (dpyinfo, target);
- if (f && XTranslateCoordinates (dpyinfo->display,
- dpyinfo->root_window,
- FRAME_X_WINDOW (f),
- root_x, root_y, &dest_x,
- &dest_y, &child_return))
+ if (f)
{
+ x_translate_coordinates (f, root_x, root_y, &dest_x, &dest_y);
+
x_dnd_movement_frame = f;
x_dnd_movement_x = dest_x;
x_dnd_movement_y = dest_y;
@@ -4877,19 +4875,16 @@ x_dnd_note_self_wheel (struct x_display_info *dpyinfo, Window target,
{
struct frame *f;
int dest_x, dest_y;
- Window child_return;
if (button < 4 || button > 7)
return;
f = x_top_window_to_frame (dpyinfo, target);
- if (f && XTranslateCoordinates (dpyinfo->display,
- dpyinfo->root_window,
- FRAME_X_WINDOW (f),
- root_x, root_y, &dest_x,
- &dest_y, &child_return))
+ if (f)
{
+ x_translate_coordinates (f, root_x, root_y, &dest_x, &dest_y);
+
x_dnd_wheel_frame = f;
x_dnd_wheel_x = dest_x;
x_dnd_wheel_y = dest_y;
@@ -4912,7 +4907,6 @@ x_dnd_note_self_drop (struct x_display_info *dpyinfo, Window target,
char **atom_names;
char *name;
int win_x, win_y, i;
- Window dummy;
if (!x_dnd_allow_current_frame
&& (FRAME_OUTER_WINDOW (x_dnd_frame)
@@ -4927,10 +4921,7 @@ x_dnd_note_self_drop (struct x_display_info *dpyinfo, Window target,
if (NILP (Vx_dnd_native_test_function))
return;
- if (!XTranslateCoordinates (dpyinfo->display, dpyinfo->root_window,
- FRAME_X_WINDOW (f), root_x, root_y,
- &win_x, &win_y, &dummy))
- return;
+ x_translate_coordinates (f, root_x, root_y, &win_x, &win_y);
/* Emacs can't respond to DND events inside the nested event loop,
so when dragging items to itself, call the test function
@@ -5148,24 +5139,20 @@ x_update_opaque_region (struct frame *f, XEvent *configure)
if (!FRAME_DISPLAY_INFO (f)->alpha_bits)
return;
- block_input ();
if (f->alpha_background < 1.0)
- XChangeProperty (FRAME_X_DISPLAY (f),
- FRAME_X_WINDOW (f),
+ XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
XA_CARDINAL, 32, PropModeReplace,
NULL, 0);
#ifndef HAVE_GTK3
else
- XChangeProperty (FRAME_X_DISPLAY (f),
- FRAME_X_WINDOW (f),
+ XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &opaque_region, 4);
#else
else if (FRAME_TOOLTIP_P (f))
- XChangeProperty (FRAME_X_DISPLAY (f),
- FRAME_X_WINDOW (f),
+ XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
FRAME_DISPLAY_INFO (f)->Xatom_net_wm_opaque_region,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &opaque_region, 4);
@@ -5183,7 +5170,6 @@ x_update_opaque_region (struct frame *f, XEvent *configure)
}
}
#endif
- unblock_input ();
}
@@ -6131,7 +6117,7 @@ x_cr_export_frames (Lisp_Object frames, cairo_surface_type_t surface_type)
unbind_to (count, Qnil);
- return CALLN (Fapply, intern ("concat"), Fnreverse (acc));
+ return CALLN (Fapply, Qconcat, Fnreverse (acc));
}
#endif /* USE_CAIRO */
@@ -7153,8 +7139,6 @@ show_back_buffer (struct frame *f)
cairo_t *cr;
#endif
- block_input ();
-
if (FRAME_X_DOUBLE_BUFFERED_P (f))
{
#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
@@ -7183,8 +7167,6 @@ show_back_buffer (struct frame *f)
}
FRAME_X_NEED_BUFFER_FLIP (f) = false;
-
- unblock_input ();
}
#endif
@@ -7292,8 +7274,12 @@ XTframe_up_to_date (struct frame *f)
static void
XTbuffer_flipping_unblocked_hook (struct frame *f)
{
+ block_input ();
+
if (FRAME_X_NEED_BUFFER_FLIP (f))
show_back_buffer (f);
+
+ unblock_input ();
}
#endif
@@ -7322,8 +7308,6 @@ x_clear_under_internal_border (struct frame *f)
: INTERNAL_BORDER_FACE_ID));
struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
- block_input ();
-
if (face)
{
unsigned long color = face->background;
@@ -7344,8 +7328,6 @@ x_clear_under_internal_border (struct frame *f)
x_clear_area (f, width - border, 0, border, height);
x_clear_area (f, 0, height - border, width, border);
}
-
- unblock_input ();
}
}
@@ -7393,7 +7375,6 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
: INTERNAL_BORDER_FACE_ID));
struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
- block_input ();
if (face)
{
unsigned long color = face->background;
@@ -7411,7 +7392,6 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
x_clear_area (f, 0, y, width, height);
x_clear_area (f, FRAME_PIXEL_WIDTH (f) - width, y, width, height);
}
- unblock_input ();
}
}
#endif
@@ -7610,12 +7590,33 @@ static void x_check_font (struct frame *, struct font *);
user time. We don't sanitize timestamps from events sent by the X
server itself because some Lisp might have set the user time to a
ridiculously large value, and this way a more reasonable timestamp
- can be obtained upon the next event. */
+ can be obtained upon the next event.
+
+ Alternatively, the server time could've overflowed.
+
+ SET_PROPERTY specifies whether or not to change the user time
+ property for the active frame. The important thing is to not set
+ the last user time upon leave events; on Metacity and GNOME Shell,
+ mapping a new frame on top of the old frame potentially causes
+ crossing events to be sent to the old frame if it contains the
+ pointer, as the new frame will initially stack above the old frame.
+ If _NET_WM_USER_TIME is changed at that point, then GNOME may get
+ notified about the user time change on the old frame before it
+ tries to focus the new frame, which will make it consider the new
+ frame (whose user time property will not have been updated at that
+ point, due to not being focused) as having been mapped
+ out-of-order, and lower the new frame, which is typically not what
+ users want. */
static void
x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
- bool send_event)
+ bool send_event, bool set_property)
{
+#if defined HAVE_XSYNC && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
+ uint_fast64_t monotonic_time;
+ uint_fast64_t monotonic_ms;
+ int_fast64_t diff_ms;
+#endif
#ifndef USE_GTK
struct frame *focus_frame;
Time old_time;
@@ -7636,9 +7637,8 @@ x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
{
/* See if the current CLOCK_MONOTONIC time is reasonably close
to the X server time. */
- uint_fast64_t monotonic_time = x_sync_current_monotonic_time ();
- uint_fast64_t monotonic_ms = monotonic_time / 1000;
- int_fast64_t diff_ms;
+ monotonic_time = x_sync_current_monotonic_time ();
+ monotonic_ms = monotonic_time / 1000;
dpyinfo->server_time_monotonic_p
= (monotonic_time != 0
@@ -7656,13 +7656,35 @@ x_display_set_last_user_time (struct x_display_info *dpyinfo, Time time,
monotonic_time,
&dpyinfo->server_time_offset))
dpyinfo->server_time_offset = 0;
+
+ /* If the server time is reasonably close to the monotonic
+ time after the latter is truncated to CARD32, simply make
+ the offset that between the server time in ms and the
+ actual time in ms. */
+
+ monotonic_ms = monotonic_ms & 0xffffffff;
+ if (!INT_SUBTRACT_WRAPV (time, monotonic_ms, &diff_ms)
+ && -500 < diff_ms && diff_ms < 500)
+ {
+ /* The server timestamp overflowed. Make the time
+ offset exactly how much it overflowed by. */
+
+ if (INT_SUBTRACT_WRAPV (monotonic_time / 1000, monotonic_ms,
+ &dpyinfo->server_time_offset)
+ || INT_MULTIPLY_WRAPV (dpyinfo->server_time_offset,
+ 1000, &dpyinfo->server_time_offset)
+ || INT_SUBTRACT_WRAPV (0, dpyinfo->server_time_offset,
+ &dpyinfo->server_time_offset))
+ dpyinfo->server_time_offset = 0;
+ }
}
}
#endif
#ifndef USE_GTK
/* Don't waste bandwidth if the time hasn't actually changed. */
- if (focus_frame && old_time != dpyinfo->last_user_time)
+ if (focus_frame && old_time != dpyinfo->last_user_time
+ && set_property)
{
time = dpyinfo->last_user_time;
@@ -7703,6 +7725,7 @@ x_set_gtk_user_time (struct frame *f, Time time)
itself. */
#ifndef USE_GTK
+
static void
x_update_frame_user_time_window (struct frame *f)
{
@@ -7766,13 +7789,14 @@ x_update_frame_user_time_window (struct frame *f)
}
}
}
+
#endif
void
x_set_last_user_time_from_lisp (struct x_display_info *dpyinfo,
Time time)
{
- x_display_set_last_user_time (dpyinfo, time, true);
+ x_display_set_last_user_time (dpyinfo, time, true, true);
}
@@ -9579,31 +9603,49 @@ x_draw_glyph_string_box (struct glyph_string *s)
#ifndef USE_CAIRO
+
static void
x_composite_image (struct glyph_string *s, Pixmap dest,
+#ifdef HAVE_XRENDER
+ Picture destination,
+#endif
int srcX, int srcY, int dstX, int dstY,
int width, int height)
{
- Display *display = FRAME_X_DISPLAY (s->f);
+ Display *display;
#ifdef HAVE_XRENDER
- if (s->img->picture && FRAME_X_PICTURE_FORMAT (s->f))
- {
- Picture destination;
- XRenderPictFormat *default_format;
- XRenderPictureAttributes attr UNINIT;
+ XRenderPictFormat *default_format;
+ XRenderPictureAttributes attr UNINIT;
+#endif
- default_format = FRAME_X_PICTURE_FORMAT (s->f);
- destination = XRenderCreatePicture (display, dest,
- default_format, 0, &attr);
+ display = FRAME_X_DISPLAY (s->f);
- XRenderComposite (display, s->img->mask_picture ? PictOpOver : PictOpSrc,
- s->img->picture, s->img->mask_picture, destination,
- srcX, srcY,
- srcX, srcY,
- dstX, dstY,
- width, height);
+#ifdef HAVE_XRENDER
+ if (s->img->picture && FRAME_X_PICTURE_FORMAT (s->f))
+ {
+ if (destination == None)
+ {
+ /* The destination picture was not specified. This means we
+ have to create a picture representing the */
+ default_format = FRAME_X_PICTURE_FORMAT (s->f);
+ destination = XRenderCreatePicture (display, dest,
+ default_format, 0, &attr);
+
+ XRenderComposite (display, (s->img->mask_picture
+ ? PictOpOver : PictOpSrc),
+ s->img->picture, s->img->mask_picture,
+ destination, srcX, srcY, srcX, srcY,
+ dstX, dstY, width, height);
+
+ XRenderFreePicture (display, destination);
+ }
+ else
+ XRenderComposite (display, (s->img->mask_picture
+ ? PictOpOver : PictOpSrc),
+ s->img->picture, s->img->mask_picture,
+ destination, srcX, srcY, srcX, srcY,
+ dstX, dstY, width, height);
- XRenderFreePicture (display, destination);
return;
}
#endif
@@ -9613,6 +9655,7 @@ x_composite_image (struct glyph_string *s, Pixmap dest,
srcX, srcY,
width, height, dstX, dstY);
}
+
#endif /* !USE_CAIRO */
@@ -9691,6 +9734,9 @@ x_draw_image_foreground (struct glyph_string *s)
image_rect.height = s->slice.height;
if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
x_composite_image (s, FRAME_X_DRAWABLE (s->f),
+#ifdef HAVE_XRENDER
+ FRAME_X_PICTURE (s->f),
+#endif
s->slice.x + r.x - x, s->slice.y + r.y - y,
r.x, r.y, r.width, r.height);
}
@@ -9704,7 +9750,12 @@ x_draw_image_foreground (struct glyph_string *s)
image_rect.width = s->slice.width;
image_rect.height = s->slice.height;
if (gui_intersect_rectangles (&clip_rect, &image_rect, &r))
- x_composite_image (s, FRAME_X_DRAWABLE (s->f), s->slice.x + r.x - x, s->slice.y + r.y - y,
+ x_composite_image (s, FRAME_X_DRAWABLE (s->f),
+#ifdef HAVE_XRENDER
+ FRAME_X_PICTURE (s->f),
+#endif
+ s->slice.x + r.x - x,
+ s->slice.y + r.y - y,
r.x, r.y, r.width, r.height);
/* When the image has a mask, we can expect that at
@@ -9870,8 +9921,11 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
XChangeGC (display, s->gc, mask, &xgcv);
x_composite_image (s, pixmap,
- s->slice.x, s->slice.y,
- x, y, s->slice.width, s->slice.height);
+#ifdef HAVE_XRENDER
+ None,
+#endif
+ s->slice.x, s->slice.y, x, y,
+ s->slice.width, s->slice.height);
XSetClipMask (display, s->gc, None);
}
else
@@ -12647,9 +12701,11 @@ xi_handle_focus_change (struct x_display_info *dpyinfo)
else
dpyinfo->client_pointer_device = device->device_id;
}
-
- if (device->focus_implicit_frame
- && device->focus_implicit_time > time)
+ /* Even if the implicit focus was set after the explicit focus
+ on this specific device, the explicit focus is what really
+ matters. So use it instead. */
+ else if (device->focus_implicit_frame
+ && device->focus_implicit_time > time)
{
new = device->focus_implicit_frame;
time = device->focus_implicit_time;
@@ -12740,11 +12796,21 @@ xi_focus_handle_for_device (struct x_display_info *dpyinfo,
switch (event->evtype)
{
case XI_FocusIn:
+ /* The last-focus-change time of the device changed, so update the
+ frame's user time. */
+ x_display_set_last_user_time (dpyinfo, event->time,
+ event->send_event, true);
+
device->focus_frame = mentioned_frame;
device->focus_frame_time = event->time;
break;
case XI_FocusOut:
+ /* The last-focus-change time of the device changed, so update the
+ frame's user time. */
+ x_display_set_last_user_time (dpyinfo, event->time,
+ event->send_event, false);
+
device->focus_frame = NULL;
/* So, unfortunately, the X Input Extension is implemented such
@@ -13521,6 +13587,98 @@ get_keysym_name (int keysym)
return value;
}
+/* Given the root and event coordinates of an X event destined for F's
+ edit window, compute the offset between that window and F's root
+ window. This information is then used as an optimization to avoid
+ synchronizing when converting coordinates from some other event to
+ F's edit window. */
+
+static void
+x_compute_root_window_offset (struct frame *f, int root_x, int root_y,
+ int event_x, int event_y)
+{
+ FRAME_X_OUTPUT (f)->window_offset_certain_p = true;
+ FRAME_X_OUTPUT (f)->root_x = root_x - event_x;
+ FRAME_X_OUTPUT (f)->root_y = root_y - event_y;
+}
+
+/* Translate the given coordinates from the root window to the edit
+ window of FRAME, taking into account any cached root window
+ offsets. This allows Emacs to avoid excessive calls to _XReply in
+ many cases while handling events, which would otherwise result in
+ slowdowns over slow network connections. */
+
+static void
+x_translate_coordinates (struct frame *f, int root_x, int root_y,
+ int *x_out, int *y_out)
+{
+ struct x_output *output;
+ Window dummy;
+
+ output = FRAME_X_OUTPUT (f);
+
+ if (output->window_offset_certain_p)
+ {
+ /* Use the cached root window offset. */
+ *x_out = root_x - output->root_x;
+ *y_out = root_y - output->root_y;
+
+ return;
+ }
+
+ /* Otherwise, do the transformation manually. Then, cache the root
+ window position. */
+ if (!XTranslateCoordinates (FRAME_X_DISPLAY (f),
+ FRAME_DISPLAY_INFO (f)->root_window,
+ FRAME_X_WINDOW (f), root_x, root_y,
+ x_out, y_out, &dummy))
+ /* Use some dummy values. This is not supposed to be called with
+ coordinates out of the screen. */
+ *x_out = 0, *y_out = 0;
+ else
+ {
+ /* Cache the root window offset of the edit window. */
+ output->window_offset_certain_p = true;
+ output->root_x = root_x - *x_out;
+ output->root_y = root_y - *y_out;
+ }
+}
+
+/* The same, but for an XIDeviceEvent. */
+
+#ifdef HAVE_XINPUT2
+
+static void
+xi_compute_root_window_offset (struct frame *f, XIDeviceEvent *xev)
+{
+ /* Truncate coordinates instead of rounding them, because that is
+ how the X server handles window hierarchy. */
+ x_compute_root_window_offset (f, xev->root_x, xev->root_y,
+ xev->event_x, xev->event_y);
+}
+
+static void
+xi_compute_root_window_offset_enter (struct frame *f, XIEnterEvent *enter)
+{
+ x_compute_root_window_offset (f, enter->root_x, enter->root_y,
+ enter->event_x, enter->event_y);
+}
+
+#ifdef HAVE_XINPUT2_4
+
+static void
+xi_compute_root_window_offset_pinch (struct frame *f, XIGesturePinchEvent *pev)
+{
+ /* Truncate coordinates instead of rounding them, because that is
+ how the X server handles window hierarchy. */
+ x_compute_root_window_offset (f, pev->root_x, pev->root_y,
+ pev->event_x, pev->event_y);
+}
+
+#endif
+
+#endif
+
static Bool
x_query_pointer_1 (struct x_display_info *dpyinfo,
int client_pointer_device, Window w,
@@ -13649,10 +13807,10 @@ x_query_pointer (Display *dpy, Window w, Window *root_return,
X server, and instead be artificially constructed from input
extension events. In these special events, the only fields that
are initialized are `time', `button', `state', `type', `window' and
- `x' and `y'. This function should not access any other fields in
- EVENT without also initializing the corresponding fields in `bv'
- under the XI_ButtonPress and XI_ButtonRelease labels inside
- `handle_one_xevent'. */
+ `x', `y', `x_root' and `y_root'. This function should not access
+ any other fields in EVENT without also initializing the
+ corresponding fields in `bv' under the XI_ButtonPress and
+ XI_ButtonRelease labels inside `handle_one_xevent'. */
static Lisp_Object
x_construct_mouse_click (struct input_event *result,
@@ -13661,7 +13819,6 @@ x_construct_mouse_click (struct input_event *result,
{
int x = event->x;
int y = event->y;
- Window dummy;
/* Make the event type NO_EVENT; we'll change that when we decide
otherwise. */
@@ -13678,9 +13835,8 @@ x_construct_mouse_click (struct input_event *result,
happen with GTK+ scroll bars, for example), translate the
coordinates so they appear at the correct position. */
if (event->window != FRAME_X_WINDOW (f))
- XTranslateCoordinates (FRAME_X_DISPLAY (f),
- event->window, FRAME_X_WINDOW (f),
- x, y, &x, &y, &dummy);
+ x_translate_coordinates (f, event->x_root, event->y_root,
+ &x, &y);
XSETINT (result->x, x);
XSETINT (result->y, y);
@@ -14035,7 +14191,8 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
< dpyinfo->last_mouse_movement_time))
x_display_set_last_user_time (dpyinfo,
dpyinfo->last_mouse_movement_time,
- dpyinfo->last_mouse_movement_time_send_event);
+ dpyinfo->last_mouse_movement_time_send_event,
+ true);
if ((!f1 || FRAME_TOOLTIP_P (f1))
&& (EQ (track_mouse, Qdropping)
@@ -14383,17 +14540,23 @@ x_protect_window_for_callback (struct x_display_info *dpyinfo,
return true;
}
-static void
+static Lisp_Object
x_unprotect_window_for_callback (struct x_display_info *dpyinfo)
{
+ Lisp_Object window;
+
if (!dpyinfo->n_protected_windows)
- emacs_abort ();
+ return Qnil;
+
+ window = dpyinfo->protected_windows[0];
dpyinfo->n_protected_windows--;
if (dpyinfo->n_protected_windows)
memmove (dpyinfo->protected_windows, &dpyinfo->protected_windows[1],
sizeof (Lisp_Object) * dpyinfo->n_protected_windows);
+
+ return window;
}
/* Send a client message with message type Xatom_Scrollbar for a
@@ -14460,30 +14623,34 @@ x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
in *IEVENT. */
static void
-x_scroll_bar_to_input_event (const XEvent *event,
+x_scroll_bar_to_input_event (struct x_display_info *dpyinfo,
+ const XEvent *event,
struct input_event *ievent)
{
- const XClientMessageEvent *ev = &event->xclient;
Lisp_Object window;
- struct window *w;
- /* See the comment in the function above. */
- intptr_t iw0 = ev->data.l[0];
- intptr_t iw1 = ev->data.l[1];
- intptr_t iw = (iw0 << 31 << 1) + (iw1 & 0xffffffffu);
- w = (struct window *) iw;
+ /* Every time a scroll bar ClientMessage event is sent, the window
+ is pushed onto a queue that is traced for garbage collection.
+ Every time we need a window for a read scroll bar event, we
+ simply read from the other side of the queue. */
+ window = x_unprotect_window_for_callback (dpyinfo);
- XSETWINDOW (window, w);
+ if (NILP (window))
+ {
+ /* This means we are getting extra scroll bar events for some
+ reason, and shouldn't be possible in practice. */
+ EVENT_INIT (*ievent);
+ return;
+ }
ievent->kind = SCROLL_BAR_CLICK_EVENT;
ievent->frame_or_window = window;
ievent->arg = Qnil;
- ievent->timestamp
- = x_get_last_toolkit_time (FRAME_DISPLAY_INFO (XFRAME (w->frame)));
+ ievent->timestamp = x_get_last_toolkit_time (dpyinfo);
ievent->code = 0;
- ievent->part = ev->data.l[2];
- ievent->x = make_fixnum (ev->data.l[3]);
- ievent->y = make_fixnum (ev->data.l[4]);
+ ievent->part = event->xclient.data.l[2];
+ ievent->x = make_fixnum (event->xclient.data.l[3]);
+ ievent->y = make_fixnum (event->xclient.data.l[4]);
ievent->modifiers = 0;
}
@@ -14491,30 +14658,34 @@ x_scroll_bar_to_input_event (const XEvent *event,
input event in *IEVENT. */
static void
-x_horizontal_scroll_bar_to_input_event (const XEvent *event,
+x_horizontal_scroll_bar_to_input_event (struct x_display_info *dpyinfo,
+ const XEvent *event,
struct input_event *ievent)
{
- const XClientMessageEvent *ev = &event->xclient;
Lisp_Object window;
- struct window *w;
- /* See the comment in the function above. */
- intptr_t iw0 = ev->data.l[0];
- intptr_t iw1 = ev->data.l[1];
- intptr_t iw = (iw0 << 31 << 1) + (iw1 & 0xffffffffu);
- w = (struct window *) iw;
+ /* Every time a scroll bar ClientMessage event is sent, the window
+ is pushed onto a queue that is traced for garbage collection.
+ Every time we need a window for a read scroll bar event, we
+ simply read from the other side of the queue. */
+ window = x_unprotect_window_for_callback (dpyinfo);
- XSETWINDOW (window, w);
+ if (NILP (window))
+ {
+ /* This means we are getting extra scroll bar events for some
+ reason, and shouldn't be possible in practice. */
+ EVENT_INIT (*ievent);
+ return;
+ }
ievent->kind = HORIZONTAL_SCROLL_BAR_CLICK_EVENT;
ievent->frame_or_window = window;
ievent->arg = Qnil;
- ievent->timestamp
- = x_get_last_toolkit_time (FRAME_DISPLAY_INFO (XFRAME (w->frame)));
+ ievent->timestamp = x_get_last_toolkit_time (dpyinfo);
ievent->code = 0;
- ievent->part = ev->data.l[2];
- ievent->x = make_fixnum (ev->data.l[3]);
- ievent->y = make_fixnum (ev->data.l[4]);
+ ievent->part = event->xclient.data.l[2];
+ ievent->x = make_fixnum (event->xclient.data.l[3]);
+ ievent->y = make_fixnum (event->xclient.data.l[4]);
ievent->modifiers = 0;
}
@@ -14637,7 +14808,8 @@ xg_scroll_callback (GtkRange *range, GtkScrollType scroll,
dpyinfo = FRAME_DISPLAY_INFO (f);
if (time != GDK_CURRENT_TIME)
- x_display_set_last_user_time (dpyinfo, time, true);
+ x_display_set_last_user_time (dpyinfo, time, true,
+ true);
switch (scroll)
{
@@ -17152,8 +17324,6 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp)
x_dnd_waiting_for_finish = false;
target = None;
}
-
- x_dnd_last_seen_toplevel = toplevel;
}
if (target != x_dnd_last_seen_window)
@@ -17184,6 +17354,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp)
}
x_dnd_action = None;
+ x_dnd_last_seen_toplevel = toplevel;
x_dnd_last_seen_window = target;
x_dnd_last_protocol_version = target_proto;
x_dnd_last_motif_style = motif_style;
@@ -17211,6 +17382,8 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp)
target, &emsg);
}
}
+ else
+ x_dnd_last_seen_toplevel = toplevel;
if (x_dnd_last_window_is_frame && target != None)
x_dnd_note_self_position (dpyinfo, target, root_x, root_y);
@@ -17578,6 +17751,53 @@ x_coords_from_dnd_message (struct x_display_info *dpyinfo,
return false;
}
+static void
+x_handle_wm_state (struct frame *f, struct input_event *ie)
+{
+ Atom type;
+ int format;
+ unsigned long nitems, bytes_after;
+ unsigned char *data;
+ unsigned long *state;
+
+ data = NULL;
+
+ if (XGetWindowProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ FRAME_DISPLAY_INFO (f)->Xatom_wm_state, 0, 2,
+ False, AnyPropertyType, &type, &format, &nitems,
+ &bytes_after, &data) != Success)
+ return;
+
+ if (!data || nitems != 2 || format != 32)
+ {
+ if (data)
+ XFree (data);
+
+ return;
+ }
+
+ state = (unsigned long *) data;
+
+ if (state[0] == NormalState && FRAME_ICONIFIED_P (f))
+ {
+ /* The frame has been deiconified. It has not been withdrawn
+ and is now visible. */
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ f->output_data.x->has_been_visible = true;
+
+ ie->kind = DEICONIFY_EVENT;
+ XSETFRAME (ie->frame_or_window, f);
+ }
+
+ /* state[0] can also be WithdrawnState, meaning that the window has
+ been withdrawn and is no longer iconified. However, Emacs sets
+ the correct flags upon withdrawing the window, so there is no
+ need to do anything here. */
+
+ XFree (data);
+}
+
/* Handles the XEvent EVENT on display DPYINFO.
*FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
@@ -17601,7 +17821,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
int do_help = 0;
#ifdef HAVE_XINPUT2
struct xi_device_t *gen_help_device;
- Time gen_help_time;
+ Time gen_help_time UNINIT;
#endif
ptrdiff_t nbytes = 0;
struct frame *any, *f = NULL;
@@ -17627,6 +17847,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
int dx, dy;
USE_SAFE_ALLOCA;
+ /* This function is not reentrant, so input should be blocked before
+ it is called. */
+
+ if (!input_blocked_p ())
+ emacs_abort ();
+
*finish = X_EVENT_NORMAL;
EVENT_INIT (inev.ie);
@@ -17676,7 +17902,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (x_dnd_last_protocol_version != -1
&& x_dnd_in_progress
- && target == x_dnd_last_seen_window
+ && target == x_dnd_last_seen_toplevel
/* The XDND documentation is not very clearly worded.
But this should be the correct behavior, since
"kDNDStatusSendHereFlag" in the reference
@@ -17901,6 +18127,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
/* Not certain about handling scroll bars here */
#endif
+ /* Set the provided time as the user time, which is
+ required for SetInputFocus to work correctly after
+ taking the input focus. */
+ x_display_set_last_user_time (dpyinfo, event->xclient.data.l[1],
+ true, true);
goto done;
}
@@ -18095,13 +18326,22 @@ handle_one_xevent (struct x_display_info *dpyinfo,
we construct an input_event. */
if (event->xclient.message_type == dpyinfo->Xatom_Scrollbar)
{
- x_scroll_bar_to_input_event (event, &inev.ie);
+ /* Convert the scroll bar event to an input event using
+ the first window entered into the scroll bar event
+ queue. */
+ x_scroll_bar_to_input_event (dpyinfo, event, &inev.ie);
+
*finish = X_EVENT_GOTO_OUT;
goto done;
}
else if (event->xclient.message_type == dpyinfo->Xatom_Horizontal_Scrollbar)
{
- x_horizontal_scroll_bar_to_input_event (event, &inev.ie);
+ /* Convert the horizontal scroll bar event to an input
+ event using the first window entered into the scroll
+ bar event queue. */
+ x_horizontal_scroll_bar_to_input_event (dpyinfo, event,
+ &inev.ie);
+
*finish = X_EVENT_GOTO_OUT;
goto done;
}
@@ -18351,6 +18591,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
}
+ if (f && event->xproperty.atom == dpyinfo->Xatom_wm_state
+ && !FRAME_X_EMBEDDED_P (f) && !FRAME_PARENT_FRAME (f))
+ /* Handle WM_STATE. We use this to clear the iconified flag
+ on a frame if it is set.
+
+ GTK builds ignore deiconifying frames on FocusIn or Expose
+ by default, and cannot wait for the window manager to
+ remove _NET_WM_STATE_HIDDEN, as it is ambiguous when not
+ set. Handling UnmapNotify also checks for
+ _NET_WM_STATE_HIDDEN, and thus suffers from the same
+ problem. */
+ x_handle_wm_state (f, &inev.ie);
+
if (f && FRAME_X_OUTPUT (f)->alpha_identical_p
&& (event->xproperty.atom
== dpyinfo->Xatom_net_wm_window_opacity))
@@ -18490,6 +18743,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
during the start of save-set processing. */
FRAME_X_OUTPUT (f)->explicit_parent = false;
+
+ /* Remove the leftover XEMBED_INFO property. */
+ XDeleteProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
+ dpyinfo->Xatom_XEMBED_INFO);
x_make_frame_visible (f);
}
#endif
@@ -18521,11 +18778,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
Window root;
unsigned int dummy_uint;
- block_input ();
XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
&root, &f->left_pos, &f->top_pos,
&dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint);
- unblock_input ();
}
x_set_frame_alpha (f);
@@ -18550,7 +18805,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
if (!FRAME_VISIBLE_P (f))
{
- block_input ();
/* By default, do not set the frame's visibility here, see
https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
The default behavior can be overridden by setting
@@ -18569,7 +18823,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
f->output_data.x->has_been_visible = true;
SET_FRAME_GARBAGED (f);
- unblock_input ();
}
else if (FRAME_GARBAGED_P (f))
{
@@ -18866,7 +19119,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case KeyPress:
x_display_set_last_user_time (dpyinfo, event->xkey.time,
- event->xkey.send_event);
+ event->xkey.send_event,
+ true);
ignore_next_mouse_click_timeout = 0;
coding = Qlatin_1;
@@ -18936,6 +19190,13 @@ handle_one_xevent (struct x_display_info *dpyinfo,
`event' itself. */
XKeyEvent xkey = event->xkey;
+ if (event->xkey.window == FRAME_X_WINDOW (f))
+ /* See the comment above x_compute_root_window_offset for
+ why this optimization is performed. */
+ x_compute_root_window_offset (f, event->xkey.x_root,
+ event->xkey.y_root,
+ event->xkey.x, event->xkey.y);
+
#ifdef HAVE_XINPUT2
Time pending_keystroke_time;
struct xi_device_t *source;
@@ -18994,7 +19255,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
&xkey, (char *) copy_bufptr,
copy_bufsiz, &keysym,
&status_return);
- coding = Qnil;
+ coding = FRAME_X_XIM_CODING (f);
if (status_return == XBufferOverflow)
{
copy_bufsiz = nbytes + 1;
@@ -19338,7 +19599,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case EnterNotify:
x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
- event->xcrossing.send_event);
+ event->xcrossing.send_event, false);
#ifdef HAVE_XINPUT2
/* For whatever reason, the X server continues to deliver
@@ -19382,6 +19643,16 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f = any;
+ if (f && event->xcrossing.window == FRAME_X_WINDOW (f))
+ x_compute_root_window_offset (f, event->xcrossing.x_root,
+ event->xcrossing.y_root,
+ event->xcrossing.x,
+ event->xcrossing.y);
+
+ /* The code below relies on the first several fields of
+ XCrossingEvent being laid out the same way as
+ XMotionEvent. */
+
if (f && x_mouse_click_focus_ignore_position)
{
ignore_next_mouse_click_timeout = (event->xmotion.time
@@ -19451,7 +19722,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
case LeaveNotify:
x_display_set_last_user_time (dpyinfo, event->xcrossing.time,
- event->xcrossing.send_event);
+ event->xcrossing.send_event, false);
#ifdef HAVE_XINPUT2
/* For whatever reason, the X server continues to deliver
@@ -19526,6 +19797,13 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|| EQ (track_mouse, Qdropping))
&& gui_mouse_grabbed (dpyinfo)))
do_help = -1;
+
+ if (event->xcrossing.window == FRAME_X_WINDOW (f))
+ x_compute_root_window_offset (f, event->xcrossing.x_root,
+ event->xcrossing.y_root,
+ event->xcrossing.x,
+ event->xcrossing.y);
+
}
#ifdef USE_GTK
/* See comment in EnterNotify above */
@@ -19569,6 +19847,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f = mouse_or_wdesc_frame (dpyinfo, event->xmotion.window);
+ if (f && event->xmotion.window == FRAME_X_WINDOW (f))
+ /* See the comment above x_compute_root_window_offset for
+ why this optimization is performed. */
+ x_compute_root_window_offset (f, event->xmotion.x_root,
+ event->xmotion.y_root,
+ event->xmotion.x,
+ event->xmotion.y);
+
if (x_dnd_in_progress
/* Handle these events normally if the recursion
level is higher than when the drag-and-drop
@@ -19675,8 +19961,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_dnd_waiting_for_finish = false;
target = None;
}
-
- x_dnd_last_seen_toplevel = toplevel;
}
if (target != x_dnd_last_seen_window)
@@ -19728,6 +20012,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
x_dnd_action = None;
+ x_dnd_last_seen_toplevel = toplevel;
x_dnd_last_seen_window = target;
x_dnd_last_protocol_version = target_proto;
x_dnd_last_motif_style = motif_style;
@@ -19756,6 +20041,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
target, &emsg);
}
}
+ else
+ x_dnd_last_seen_toplevel = toplevel;
if (x_dnd_last_window_is_frame && target != None)
x_dnd_note_self_position (dpyinfo, target,
@@ -19832,10 +20119,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xmotion.window != FRAME_X_WINDOW (f))
{
- XTranslateCoordinates (FRAME_X_DISPLAY (f),
- xmotion.window, FRAME_X_WINDOW (f),
- xmotion.x, xmotion.y, &xmotion.x,
- &xmotion.y, &xmotion.subwindow);
+ x_translate_coordinates (f, xmotion.x_root, xmotion.y_root,
+ &xmotion.x, &xmotion.y);
xmotion.window = FRAME_X_WINDOW (f);
}
@@ -20058,17 +20343,21 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
f = x_top_window_to_frame (dpyinfo, configureEvent.xconfigure.window);
+
+ /* This means we can no longer be certain of the root window
+ coordinates of any's edit window. */
+ if (any)
+ FRAME_X_OUTPUT (any)->window_offset_certain_p = false;
+
/* Unfortunately, we need to call x_drop_xrender_surfaces for
_all_ ConfigureNotify events, otherwise we miss some and
flicker. Don't try to optimize these calls by looking only
for size changes: that's not sufficient. We miss some
surface invalidations and flicker. */
- block_input ();
#ifdef HAVE_XDBE
if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
x_drop_xrender_surfaces (f);
#endif
- unblock_input ();
#if defined USE_CAIRO && !defined USE_GTK
if (f)
x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width,
@@ -20098,10 +20387,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f->new_width, f->new_height);
#ifdef HAVE_XDBE
- block_input ();
if (FRAME_X_DOUBLE_BUFFERED_P (f))
x_drop_xrender_surfaces (f);
- unblock_input ();
#endif
xg_frame_resized (f, configureEvent.xconfigure.width,
configureEvent.xconfigure.height);
@@ -20191,11 +20478,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
Window root;
unsigned int dummy_uint;
- block_input ();
XGetGeometry (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
&root, &f->left_pos, &f->top_pos,
&dummy_uint, &dummy_uint, &dummy_uint, &dummy_uint);
- unblock_input ();
}
if (!FRAME_TOOLTIP_P (f)
@@ -20252,7 +20537,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
if (event->xbutton.type == ButtonPress)
x_display_set_last_user_time (dpyinfo, event->xbutton.time,
- event->xbutton.send_event);
+ event->xbutton.send_event, true);
#ifdef HAVE_XWIDGETS
struct xwidget_view *xvw = xwidget_view_from_window (event->xbutton.window);
@@ -20293,10 +20578,18 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
+ if (f && event->xbutton.window == FRAME_X_WINDOW (f))
+ /* See the comment above x_compute_root_window_offset
+ for why this optimization is performed. */
+ x_compute_root_window_offset (f, event->xbutton.x_root,
+ event->xbutton.y_root,
+ event->xbutton.x,
+ event->xbutton.y);
+
if (event->type == ButtonPress)
{
x_display_set_last_user_time (dpyinfo, event->xbutton.time,
- event->xbutton.send_event);
+ event->xbutton.send_event, true);
dpyinfo->grabbed |= (1 << event->xbutton.button);
dpyinfo->last_mouse_frame = f;
@@ -20373,7 +20666,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
else if (x_dnd_last_seen_window != None
&& x_dnd_last_protocol_version != -1)
{
- x_dnd_pending_finish_target = x_dnd_last_seen_window;
+ x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
x_dnd_waiting_for_finish
@@ -20466,6 +20759,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
dpyinfo->last_mouse_glyph_frame = NULL;
f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window);
+
+ if (f && event->xbutton.window == FRAME_X_WINDOW (f))
+ /* See the comment above x_compute_root_window_offset
+ for why this optimization is performed. */
+ x_compute_root_window_offset (f, event->xbutton.x_root,
+ event->xbutton.y_root,
+ event->xbutton.x,
+ event->xbutton.y);
+
if (f && event->xbutton.type == ButtonPress
&& !popup_activated ()
&& !x_window_to_scroll_bar (event->xbutton.display,
@@ -20480,12 +20782,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
{
- block_input ();
XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
RevertToParent, event->xbutton.time);
if (FRAME_PARENT_FRAME (f))
XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
- unblock_input ();
}
}
@@ -20846,7 +21146,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
ev.send_event = enter->send_event;
x_display_set_last_user_time (dpyinfo, enter->time,
- enter->send_event);
+ enter->send_event, false);
#ifdef USE_MOTIF
use_copy = true;
@@ -20914,6 +21214,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f = any;
+ if (f && enter->event == FRAME_X_WINDOW (f))
+ xi_compute_root_window_offset_enter (f, enter);
+
if (f && x_mouse_click_focus_ignore_position)
{
ignore_next_mouse_click_timeout = (enter->time
@@ -21029,7 +21332,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
x_display_set_last_user_time (dpyinfo, leave->time,
- leave->send_event);
+ leave->send_event, false);
#ifdef HAVE_XWIDGETS
{
@@ -21110,6 +21413,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|| EQ (track_mouse, Qdropping))
&& gui_mouse_grabbed (dpyinfo)))
do_help = -1;
+
+ if (f && leave->event == FRAME_X_WINDOW (f))
+ xi_compute_root_window_offset_enter (f, leave);
}
#ifdef USE_GTK
/* See comment in EnterNotify above */
@@ -21153,8 +21459,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
goto XI_OTHER;
#endif
- Window dummy;
-
#ifdef HAVE_XINPUT2_1
#ifdef HAVE_XWIDGETS
struct xwidget_view *xv = xwidget_view_from_window (xev->event);
@@ -21232,11 +21536,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
real_y = lrint (xev->event_y + bar->top);
}
else
- XTranslateCoordinates (dpyinfo->display,
- xev->event, FRAME_X_WINDOW (f),
- lrint (xev->event_x),
- lrint (xev->event_y),
- &real_x, &real_y, &dummy);
+ x_translate_coordinates (f,
+ lrint (xev->root_x),
+ lrint (xev->root_y),
+ &real_x, &real_y);
}
else
{
@@ -21304,7 +21607,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
state = xi_convert_event_state (xev);
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
if (found_valuator)
xwidget_scroll (xv, xev->event_x, xev->event_y,
@@ -21324,7 +21627,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (found_valuator)
{
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
#if defined USE_GTK && !defined HAVE_GTK3
@@ -21438,6 +21741,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f = mouse_or_wdesc_frame (dpyinfo, xev->event);
+ if (f && xev->event == FRAME_X_WINDOW (f))
+ /* See the comment above x_compute_root_window_offset
+ for why this optimization is performed. */
+ xi_compute_root_window_offset (f, xev);
+
if (x_dnd_in_progress
/* Handle these events normally if the recursion
level is higher than when the drag-and-drop
@@ -21546,8 +21854,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_dnd_waiting_for_finish = false;
target = None;
}
-
- x_dnd_last_seen_toplevel = toplevel;
}
if (target != x_dnd_last_seen_window)
@@ -21601,6 +21907,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
x_dnd_action = None;
+ x_dnd_last_seen_toplevel = toplevel;
x_dnd_last_seen_window = target;
x_dnd_last_protocol_version = target_proto;
x_dnd_last_motif_style = motif_style;
@@ -21629,6 +21936,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
target, &emsg);
}
}
+ else
+ x_dnd_last_seen_toplevel = toplevel;
if (x_dnd_last_window_is_frame && target != None)
x_dnd_note_self_position (dpyinfo, target,
@@ -21685,9 +21994,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
if (xev->event != FRAME_X_WINDOW (f))
{
- XTranslateCoordinates (FRAME_X_DISPLAY (f),
- xev->event, FRAME_X_WINDOW (f),
- ev.x, ev.y, &ev.x, &ev.y, &dummy);
+ x_translate_coordinates (f, lrint (xev->root_x),
+ lrint (xev->root_y),
+ &ev.x, &ev.y);
ev.window = FRAME_X_WINDOW (f);
}
@@ -21793,6 +22102,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f = mouse_or_wdesc_frame (dpyinfo, xev->event);
device = xi_device_from_id (dpyinfo, xev->deviceid);
+ if (f && xev->event == FRAME_X_WINDOW (f))
+ /* See the comment above
+ x_compute_root_window_offset for why this
+ optimization is performed. */
+ xi_compute_root_window_offset (f, xev);
+
/* Don't track grab status for emulated pointer
events, because they are ignored by the regular
mouse click processing code. */
@@ -21803,7 +22118,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xev->evtype == XI_ButtonPress)
{
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
dpyinfo->grabbed |= (1 << xev->detail);
dpyinfo->last_mouse_frame = f;
@@ -21846,7 +22161,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xev->flags & XIPointerEmulated)
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
#endif
x_dnd_note_self_wheel (dpyinfo,
x_dnd_last_seen_window,
@@ -21910,7 +22225,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
else if (x_dnd_last_seen_window != None
&& x_dnd_last_protocol_version != -1)
{
- x_dnd_pending_finish_target = x_dnd_last_seen_window;
+ x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
x_dnd_waiting_for_finish
@@ -22082,7 +22397,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xev->evtype == XI_ButtonPress)
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
source = xi_device_from_id (dpyinfo, xev->sourceid);
device = xi_device_from_id (dpyinfo, xev->deviceid);
@@ -22124,6 +22439,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
bv.x = lrint (xev->event_x);
bv.y = lrint (xev->event_y);
+ bv.x_root = lrint (xev->root_x);
+ bv.y_root = lrint (xev->root_y);
bv.window = xev->event;
bv.state = xi_convert_event_state (xev);
bv.time = xev->time;
@@ -22132,6 +22449,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f = mouse_or_wdesc_frame (dpyinfo, xev->event);
+ if (f && xev->event == FRAME_X_WINDOW (f))
+ /* See the comment above x_compute_root_window_offset
+ for why this optimization is performed. */
+ xi_compute_root_window_offset (f, xev);
+
if (f && xev->evtype == XI_ButtonPress
&& !popup_activated ()
&& !x_window_to_scroll_bar (dpyinfo->display, xev->event, 2)
@@ -22145,7 +22467,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf)))
{
- block_input ();
#if defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT)
if (device)
{
@@ -22168,7 +22489,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
if (FRAME_PARENT_FRAME (f))
XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
- unblock_input ();
}
}
@@ -22185,9 +22505,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#ifdef USE_GTK
if (!f)
{
- int real_x = lrint (xev->event_x);
- int real_y = lrint (xev->event_y);
- Window child;
+ int real_x = lrint (xev->root_x);
+ int real_y = lrint (xev->root_y);
f = x_any_window_to_frame (dpyinfo, xev->event);
@@ -22196,9 +22515,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (xev->evtype == XI_ButtonRelease)
{
if (FRAME_X_WINDOW (f) != xev->event)
- XTranslateCoordinates (dpyinfo->display, xev->event,
- FRAME_X_WINDOW (f), real_x,
- real_y, &real_x, &real_y, &child);
+ x_translate_coordinates (f, real_x, real_y,
+ &real_x, &real_y);
if (xev->detail <= 5)
inev.ie.kind = WHEEL_EVENT;
@@ -22458,11 +22776,16 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
ignore_next_mouse_click_timeout = 0;
f = x_any_window_to_frame (dpyinfo, xev->event);
+ if (f && xev->event == FRAME_X_WINDOW (f))
+ /* See the comment above x_compute_root_window_offset
+ for why this optimization is performed. */
+ xi_compute_root_window_offset (f, xev);
+
/* GTK handles TAB events in an undesirable manner, so
keyboard events are always dropped. But as a side
effect, the user time will no longer be set by GDK,
@@ -22621,7 +22944,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
&xkey, (char *) copy_bufptr,
copy_bufsiz, &keysym,
&status_return);
- coding = Qnil;
+ coding = FRAME_X_XIM_CODING (f);
if (status_return == XBufferOverflow)
{
@@ -22987,24 +23310,36 @@ handle_one_xevent (struct x_display_info *dpyinfo,
any_changed = true;
}
- x_catch_errors (dpyinfo->display);
- info = XIQueryDevice (dpyinfo->display, hev->info[i].deviceid,
- &ndevices);
- x_uncatch_errors ();
+ /* Under unknown circumstances, multiple
+ XIDeviceEnabled events are sent at once,
+ causing the device to be duplicated. Check
+ that the device doesn't exist before adding
+ it. */
- if (info && info->enabled)
+ if (!xi_device_from_id (dpyinfo,
+ hev->info[i].deviceid))
{
- dpyinfo->devices
- = xrealloc (dpyinfo->devices, (sizeof *dpyinfo->devices
- * ++dpyinfo->num_devices));
- memset (dpyinfo->devices + dpyinfo->num_devices - 1,
- 0, sizeof *dpyinfo->devices);
- device = &dpyinfo->devices[dpyinfo->num_devices - 1];
- xi_populate_device_from_info (device, info);
- }
+ x_catch_errors (dpyinfo->display);
+ info = XIQueryDevice (dpyinfo->display,
+ hev->info[i].deviceid,
+ &ndevices);
+ x_uncatch_errors ();
- if (info)
- XIFreeDeviceInfo (info);
+ if (info && info->enabled)
+ {
+ dpyinfo->devices
+ = xrealloc (dpyinfo->devices,
+ (sizeof *dpyinfo->devices
+ * ++dpyinfo->num_devices));
+ memset (dpyinfo->devices + dpyinfo->num_devices - 1,
+ 0, sizeof *dpyinfo->devices);
+ device = &dpyinfo->devices[dpyinfo->num_devices - 1];
+ xi_populate_device_from_info (device, info);
+ }
+
+ if (info)
+ XIFreeDeviceInfo (info);
+ }
}
else if (hev->info[i].flags & XIDeviceDisabled)
disabled[n_disabled++] = hev->info[i].deviceid;
@@ -23080,7 +23415,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
device = xi_device_from_id (dpyinfo, xev->deviceid);
source = xi_device_from_id (dpyinfo, xev->sourceid);
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
if (!device)
goto XI_OTHER;
@@ -23090,6 +23425,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
f = x_window_to_frame (dpyinfo, xev->event);
+ if (f)
+ /* See the comment above x_compute_root_window_offset
+ for why this optimization is performed. */
+ xi_compute_root_window_offset (f, xev);
+
#ifdef HAVE_GTK3
menu_bar_p = (f && FRAME_X_OUTPUT (f)->menubar_widget
&& xg_event_is_for_menubar (f, event));
@@ -23173,7 +23513,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
device = xi_device_from_id (dpyinfo, xev->deviceid);
source = xi_device_from_id (dpyinfo, xev->sourceid);
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
if (!device)
goto XI_OTHER;
@@ -23220,7 +23560,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
device = xi_device_from_id (dpyinfo, xev->deviceid);
source = xi_device_from_id (dpyinfo, xev->sourceid);
x_display_set_last_user_time (dpyinfo, xev->time,
- xev->send_event);
+ xev->send_event, true);
if (!device)
goto XI_OTHER;
@@ -23261,7 +23601,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
device = xi_device_from_id (dpyinfo, pev->deviceid);
source = xi_device_from_id (dpyinfo, pev->sourceid);
x_display_set_last_user_time (dpyinfo, pev->time,
- pev->send_event);
+ pev->send_event, true);
if (!device)
goto XI_OTHER;
@@ -23278,8 +23618,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
any = x_window_to_frame (dpyinfo, pev->event);
+
if (any)
{
+ if (pev->event == FRAME_X_WINDOW (any))
+ xi_compute_root_window_offset_pinch (any, pev);
+
inev.ie.kind = PINCH_EVENT;
inev.ie.modifiers = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (any),
pev->mods.effective);
@@ -23673,7 +24017,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
OTHER:
#ifdef USE_X_TOOLKIT
- block_input ();
if (*finish != X_EVENT_DROP)
{
/* Ignore some obviously bogus ConfigureNotify events that
@@ -23690,7 +24033,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#endif
}
}
- unblock_input ();
#endif /* USE_X_TOOLKIT */
#if defined USE_GTK && !defined HAVE_GTK3 && defined HAVE_XINPUT2
if (*finish != X_EVENT_DROP && copy)
@@ -23712,12 +24054,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
count++;
}
-#ifdef USE_TOOLKIT_SCROLL_BARS
- if (event->xany.type == ClientMessage
- && inev.ie.kind == SCROLL_BAR_CLICK_EVENT)
- x_unprotect_window_for_callback (dpyinfo);
-#endif
-
if (do_help
&& !(hold_quit && hold_quit->kind != NO_EVENT))
{
@@ -25231,6 +25567,39 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
#ifdef HAVE_X11R6
+/* If preedit text is set on F, cancel preedit, free the text, and
+ generate the appropriate events to cancel the preedit display.
+
+ This is mainly useful when the connection to the IM server is
+ dropped during preconversion. */
+
+static void
+x_maybe_clear_preedit (struct frame *f)
+{
+ struct x_output *output;
+ struct input_event ie;
+
+ output = FRAME_X_OUTPUT (f);
+
+ if (!output->preedit_chars)
+ return;
+
+ EVENT_INIT (ie);
+ ie.kind = PREEDIT_TEXT_EVENT;
+ ie.arg = Qnil;
+ XSETFRAME (ie.frame_or_window, f);
+ XSETINT (ie.x, 0);
+ XSETINT (ie.y, 0);
+ kbd_buffer_store_event (&ie);
+
+ xfree (output->preedit_chars);
+
+ output->preedit_size = 0;
+ output->preedit_active = false;
+ output->preedit_chars = NULL;
+ output->preedit_caret = 0;
+}
+
/* XIM destroy callback function, which is called whenever the
connection to input method XIM dies. CLIENT_DATA contains a
pointer to the x_display_info structure corresponding to XIM. */
@@ -25251,6 +25620,9 @@ xim_destroy_callback (XIM xim, XPointer client_data, XPointer call_data)
{
FRAME_XIC (f) = NULL;
xic_free_xfontset (f);
+
+ /* Free the preedit text if necessary. */
+ x_maybe_clear_preedit (f);
}
}
@@ -25268,9 +25640,10 @@ xim_destroy_callback (XIM xim, XPointer client_data, XPointer call_data)
static void
xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name)
{
+#ifdef HAVE_XIM
XIM xim;
+ const char *locale;
-#ifdef HAVE_XIM
if (use_xim)
{
if (dpyinfo->xim)
@@ -25293,6 +25666,14 @@ xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name)
destroy.client_data = (XPointer)dpyinfo;
XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
#endif
+
+ locale = XLocaleOfIM (xim);
+
+ /* Now try to determine the coding system that should be
+ used. locale is in Host Portable Character Encoding, and
+ as such can be passed to build_string as is. */
+ dpyinfo->xim_coding = safe_call1 (Vx_input_coding_function,
+ build_string (locale));
}
}
@@ -26622,8 +27003,7 @@ x_ewmh_activate_frame (struct frame *f)
dpyinfo = FRAME_DISPLAY_INFO (f);
- if (FRAME_VISIBLE_P (f)
- && x_wm_supports (f, dpyinfo->Xatom_net_active_window))
+ if (FRAME_VISIBLE_P (f))
{
/* See the documentation at
https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html
@@ -26683,14 +27063,37 @@ x_focus_frame (struct frame *f, bool noactivate)
xembed_request_focus (f);
else
{
+ if (!noactivate
+ && x_wm_supports (f, dpyinfo->Xatom_net_active_window))
+ {
+ /* When window manager activation is possible, use it
+ instead. The window manager is expected to perform any
+ necessary actions such as raising the frame, moving it to
+ the current workspace, and mapping it, etc, before moving
+ input focus to the frame. */
+ x_ewmh_activate_frame (f);
+ return;
+ }
+
/* Ignore any BadMatch error this request might result in. */
x_ignore_errors_for_next_request (dpyinfo);
- XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
- RevertToParent, CurrentTime);
+ if (NILP (Vx_no_window_manager))
+ XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ /* It is invalid to use CurrentTime according to
+ the ICCCM:
+
+ Clients that use a SetInputFocus request must
+ set the time field to the timestamp of the
+ event that caused them to make the
+ attempt. [...] Note that clients must not use
+ CurrentTime in the time field. */
+ RevertToParent, dpyinfo->last_user_time);
+ else
+ XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ /* But when no window manager is in use, we
+ don't care. */
+ RevertToParent, CurrentTime);
x_stop_ignoring_errors (dpyinfo);
-
- if (!noactivate)
- x_ewmh_activate_frame (f);
}
}
@@ -27322,6 +27725,13 @@ x_free_frame_resources (struct frame *f)
#if defined HAVE_XSYNCTRIGGERFENCE && !defined USE_GTK && defined HAVE_CLOCK_GETTIME
x_sync_free_fences (f);
#endif
+
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ /* Since the frame was destroyed, we can no longer guarantee
+ that scroll bar events will be received. Clear
+ protected_windows. */
+ dpyinfo->n_protected_windows = 0;
+#endif
}
#ifdef HAVE_GTK3
@@ -27347,6 +27757,16 @@ x_free_frame_resources (struct frame *f)
if (f == hlinfo->mouse_face_mouse_frame)
reset_mouse_highlight (hlinfo);
+#ifdef HAVE_XINPUT2
+ /* Consider a frame being unfocused with no following FocusIn event
+ while an older focus from another seat exists. The client
+ pointer should then revert to the other seat, so handle potential
+ focus changes. */
+
+ if (dpyinfo->supports_xi2)
+ xi_handle_focus_change (dpyinfo);
+#endif
+
unblock_input ();
}
@@ -27616,6 +28036,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
Window window = FRAME_OUTER_WINDOW (f);
#ifdef USE_X_TOOLKIT
WMShellWidget shell;
+ bool hints_changed;
#endif
if (!window)
@@ -27642,8 +28063,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
shell->wm.size_hints.flags |= USPosition;
}
- widget_update_wm_size_hints (f->output_data.x->widget,
- f->output_data.x->edit_widget);
+ hints_changed
+ = widget_update_wm_size_hints (f->output_data.x->widget,
+ f->output_data.x->edit_widget);
#ifdef USE_MOTIF
/* Do this all over again for the benefit of Motif, which always
@@ -27656,6 +28078,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
shell->wm.size_hints.flags &= ~PPosition;
shell->wm.size_hints.flags |= USPosition;
}
+#endif
/* Drill hints into Motif, since it keeps setting its own. */
size_hints.flags = shell->wm.size_hints.flags;
@@ -27673,15 +28096,23 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
size_hints.min_aspect.y = shell->wm.size_hints.min_aspect.y;
size_hints.max_aspect.x = shell->wm.size_hints.max_aspect.x;
size_hints.max_aspect.y = shell->wm.size_hints.max_aspect.y;
-#ifdef HAVE_X11XTR6
size_hints.base_width = shell->wm.base_width;
size_hints.base_height = shell->wm.base_height;
size_hints.win_gravity = shell->wm.win_gravity;
-#endif
+#ifdef USE_MOTIF
XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
XtWindow (f->output_data.x->widget),
&size_hints);
+#else
+ /* In many cases, widget_update_wm_size_hints will not have
+ updated the size hints if only flags changed. When that
+ happens, set the WM hints manually. */
+
+ if (!hints_changed)
+ XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
+ XtWindow (f->output_data.x->widget),
+ &size_hints);
#endif
return;
@@ -28066,7 +28497,7 @@ xi_select_hierarchy_events (struct x_display_info *dpyinfo)
extension.
Value is 0 if GTK was not built with the input extension, or if it
- was explictly disabled, 1 if GTK enabled the input extension and
+ was explicitly disabled, 1 if GTK enabled the input extension and
the version was successfully determined, and 2 if that information
could not be determined. */
@@ -28096,9 +28527,10 @@ xi_check_toolkit (Display *display)
#endif
-/* Open a connection to X display DISPLAY_NAME, and return
- the structure that describes the open display.
- If we cannot contact the display, return null. */
+/* Open a connection to X display DISPLAY_NAME, and return the
+ structure that describes the open display. If obtaining the XCB
+ connection or toolkit-specific display fails, return NULL. Signal
+ an error if opening the display itself failed. */
struct x_display_info *
x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
@@ -28125,9 +28557,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
++x_initialized;
}
- if (! x_display_ok (SSDATA (display_name)))
+#if defined USE_X_TOOLKIT || defined USE_GTK
+
+ if (!x_display_ok (SSDATA (display_name)))
error ("Display %s can't be opened", SSDATA (display_name));
+#endif
+
#ifdef USE_GTK
{
#define NUM_ARGV 10
@@ -28254,6 +28690,15 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
/* Detect failure. */
if (dpy == 0)
{
+#if !defined USE_X_TOOLKIT && !defined USE_GTK
+ /* Avoid opening a display three times (once in dispextern.c
+ upon startup, once in x_display_ok, and once above) to
+ determine whether or not the display is alive on no toolkit
+ builds, where no toolkit initialization happens at all. */
+
+ error ("Display %s can't be opened", SSDATA (display_name));
+#endif
+
unblock_input ();
return 0;
}
@@ -28938,7 +29383,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
#endif
#ifdef HAVE_X_I18N
- xim_initialize (dpyinfo, resource_name);
+ /* Avoid initializing input methods if the X library does not
+ support Emacs's locale. When the current locale is not
+ supported, decoding input method strings becomes undefined. */
+ if (XSupportsLocale ())
+ xim_initialize (dpyinfo, resource_name);
#endif
xsettings_initialize (dpyinfo);
@@ -29598,7 +30047,7 @@ mark_xterm (void)
}
#if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \
- || defined HAVE_XRANDR || defined USE_GTK
+ || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
{
#ifdef HAVE_XINPUT2
@@ -29612,6 +30061,9 @@ mark_xterm (void)
#if defined HAVE_XRANDR || defined USE_GTK
mark_object (dpyinfo->last_monitor_attributes_list);
#endif
+#if defined HAVE_X_I18N
+ mark_object (dpyinfo->xim_coding);
+#endif
}
#endif
}
@@ -29821,6 +30273,9 @@ syms_of_xterm (void)
x_dnd_unsupported_drop_data = Qnil;
staticpro (&x_dnd_unsupported_drop_data);
+ /* Used by x_cr_export_frames. */
+ DEFSYM (Qconcat, "concat");
+
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
DEFSYM (Qlatin_1, "latin-1");
DEFSYM (Qnow, "now");
@@ -30137,4 +30592,18 @@ on the same display.
In addition, when this variable is a list, only preserve the
selections whose names are contained within. */);
Vx_auto_preserve_selections = list2 (QCLIPBOARD, QPRIMARY);
+
+ DEFVAR_LISP ("x-input-coding-system", Vx_input_coding_system,
+ doc: /* Coding system used for input from X input methods.
+If a symbol and non-nil, this is the coding system that will be used
+to decode input from X input methods. It does not affect input from
+GTK native input methods enabled through `x-gtk-use-native-input'. */);
+ Vx_input_coding_system = Qnil;
+
+ DEFVAR_LISP ("x-input-coding-function", Vx_input_coding_function,
+ doc: /* Function used to determine the coding system used by input methods.
+It should accept a single argument, a string describing the locale of
+the input method, and return a coding system that can decode keyboard
+input generated by said input method. */);
+ Vx_input_coding_function = Qnil;
}
diff --git a/src/xterm.h b/src/xterm.h
index d6ff15e40f7..b68a234faa5 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -580,6 +580,9 @@ struct x_display_info
XIMStyles *xim_styles;
struct xim_inst_t *xim_callback_data;
XIMStyle preferred_xim_style;
+
+ /* The named coding system to use for this input method. */
+ Lisp_Object xim_coding;
#endif
/* A cache mapping color names to RGB values. */
@@ -1196,6 +1199,15 @@ struct x_output
XIEventMask *xi_masks;
int num_xi_masks;
#endif
+
+ /* Whether or not we are certain we know the offset from the root
+ window to this frame. */
+ bool window_offset_certain_p;
+
+ /* The offset of the edit window from the root window. This is
+ strictly an optimization to avoid extraneous synchronizing in
+ some cases. */
+ int root_x, root_y;
};
enum
@@ -1339,6 +1351,12 @@ extern void x_mark_frame_dirty (struct frame *f);
#define FRAME_X_XIM_STYLES(f) (FRAME_DISPLAY_INFO (f)->xim_styles)
#define FRAME_XIC_STYLE(f) ((f)->output_data.x->xic_style)
#define FRAME_XIC_FONTSET(f) ((f)->output_data.x->xic_xfs)
+#define FRAME_X_XIM_CODING(f) \
+ (SYMBOLP (Vx_input_coding_system) \
+ ? Vx_input_coding_system \
+ : (!NILP (FRAME_DISPLAY_INFO (f)->xim_coding) \
+ ? FRAME_DISPLAY_INFO(f)->xim_coding \
+ : Vlocale_coding_system))
/* X-specific scroll bar stuff. */
diff --git a/test/lisp/ansi-osc-tests.el b/test/lisp/ansi-osc-tests.el
new file mode 100644
index 00000000000..b3d66fb036c
--- /dev/null
+++ b/test/lisp/ansi-osc-tests.el
@@ -0,0 +1,57 @@
+;;; osc-tests.el --- Tests for osc.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Matthias Meulien <orontee@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'ansi-osc)
+(require 'ert)
+
+(defvar ansi-osc-tests--strings
+ `(
+ ("Hello World" "Hello World")
+
+ ;; window title
+ ("Buffer \e]2;A window title\e\\content" "Buffer content")
+
+ ;; window title
+ ("Unfinished \e]2;window title" "Unfinished \e]2;window title")
+
+ ;; current directory
+ ("\e]7;file://127.0.0.1/tmp\e\\user@host$ " "user@host$ ")
+
+ ;; hyperlink
+ ("\e]8;;http://example.com\e\\This is a link\e]8;;\e\\" "This is a link")
+ ))
+;; Don't output those strings to stdout since they may have
+;; side-effects on the environment
+
+(ert-deftest ansi-osc-tests-apply-region-no-handlers ()
+ (let ((ansi-osc-handlers nil))
+ (pcase-dolist (`(,input ,text) ansi-osc-tests--strings)
+ (with-temp-buffer
+ (insert input)
+ (ansi-osc-apply-on-region (point-min) (point-max))
+ (should (equal (buffer-string) text))))))
diff --git a/test/lisp/calendar/icalendar-tests.el b/test/lisp/calendar/icalendar-tests.el
index 7f8cd479146..2e9353a09b8 100644
--- a/test/lisp/calendar/icalendar-tests.el
+++ b/test/lisp/calendar/icalendar-tests.el
@@ -1310,7 +1310,7 @@ SUMMARY:and diary-anniversary
"import-real-world-2003-05-29.diary-european"
"import-real-world-2003-05-29.diary-american")
- ;; created with http://apps.marudot.com/ical/
+ ;; created with https://apps.marudot.com/ical/
(icalendar-tests--test-import "import-real-world-no-dst.ics"
nil
"import-real-world-no-dst.diary-european"
diff --git a/test/lisp/cedet/semantic-utest.el b/test/lisp/cedet/semantic-utest.el
index 24a467474b9..b577b198089 100644
--- a/test/lisp/cedet/semantic-utest.el
+++ b/test/lisp/cedet/semantic-utest.el
@@ -609,7 +609,6 @@ INSERTME is the text to be inserted after the deletion."
(semantic-utest-generic (semantic-utest-fname "phptest.php") semantic-utest-PHP-buffer-contents semantic-utest-PHP-name-contents '("fun1") "fun2" "%^@")
)
-;look at http://mfgames.com/linux/csharp-mode
(ert-deftest semantic-utest-Csharp() ;; hmm i don't even know how to edit a scharp file. need a csharp mode implementation i suppose
(skip-unless (featurep 'csharp-mode))
(semantic-utest-generic (semantic-utest-fname "csharptest.cs") semantic-utest-Csharp-buffer-contents semantic-utest-Csharp-name-contents '("fun2") "//1" "//deleted line")
diff --git a/test/lisp/dnd-tests.el b/test/lisp/dnd-tests.el
index 88f6e694577..bdadc0f2801 100644
--- a/test/lisp/dnd-tests.el
+++ b/test/lisp/dnd-tests.el
@@ -52,13 +52,13 @@
;; Verify that the action is valid and pretend the drag succeeded
;; (by returning the action).
(cl-ecase action
- ('XdndActionCopy action)
- ('XdndActionMove action)
- ('XdndActionLink action)
+ (XdndActionCopy action)
+ (XdndActionMove action)
+ (XdndActionLink action)
;; These two are not technically valid, but x-begin-drag accepts
;; them anyway.
- ('XdndActionPrivate action)
- ('XdndActionAsk 'XdndActionPrivate))))
+ (XdndActionPrivate action)
+ (XdndActionAsk 'XdndActionPrivate))))
;; This doesn't work during tests.
(defalias 'gui-set-selection
@@ -416,7 +416,7 @@ This function only tries to handle strings."
;; system specific test is in x-dnd-tests.el. When running this
;; interactively, keep in mind that there are only two file managers
;; which are known to implement XDS correctly: System G (see
- ;; http://nps-systemg.sourceforge.net), and Emacs itself. GTK file
+ ;; https://nps-systemg.sourceforge.net), and Emacs itself. GTK file
;; managers such as Nautilus will not work, since they prefer the
;; `text/uri-list' selection target to `XdndDirectSave0', contrary
;; to the XDS specification.
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index 5d7e905cfa3..d34737e6090 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -901,7 +901,7 @@ baz\"\""
(should (equal (buffer-string) "int main () {\n \n}"))))
(ert-deftest electric-layout-control-reindentation ()
- "Same as `emacs-lisp-int-main-kernel-style', but checking
+ "Same as `electric-layout-int-main-kernel-style', but checking
Bug#35254."
(ert-with-test-buffer ()
(plainer-c-mode)
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-set-nonvariable.el b/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-set-nonvariable.el
deleted file mode 100644
index 0c76c4d388b..00000000000
--- a/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-set-nonvariable.el
+++ /dev/null
@@ -1,3 +0,0 @@
-;;; -*- lexical-binding: t -*-
-(defun foo ()
- (set '(a) nil))
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-function-signature.el b/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-function-signature.el
new file mode 100644
index 00000000000..e83f516e58c
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-function-signature.el
@@ -0,0 +1,4 @@
+;;; -*- lexical-binding: t -*-
+(defun foo-bar ()
+ "This should not warn:
+(fn COMMAND &rest ARGS &key (MARGIN (rx bol (+ \" \"))) (ARGUMENT (rx \"-\" (+ (any \"-\" alnum)) (32 \"=\"))) (METAVAR (rx (32 \" \") (or (+ (any alnum \"_-\")) (seq \"[\" (+? nonl) \"]\") (seq \"<\" (+? nonl) \">\") (seq \"{\" (+? nonl) \"}\")))) (SEPARATOR (rx \", \" symbol-start)) (DESCRIPTION (rx (* nonl) (* \"\\=\\n\" (>= 9 \" \") (* nonl)))) NARROW-START NARROW-END)")
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index bc9f8d802a6..e7c308213e4 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -59,6 +59,8 @@ inner loops respectively."
(setq i (1- i)))
res))
+(defvar bytecomp-tests--xx nil)
+
(defconst bytecomp-tests--test-cases
'(
;; some functional tests
@@ -692,6 +694,16 @@ inner loops respectively."
(f (lambda ()
(let ((y x)) (list y 3 y)))))
(funcall f))
+
+ ;; Test rewriting of `set' to `setq' (only done on dynamic variables).
+ (let ((xx 1)) (set 'xx 2) xx)
+ (let ((bytecomp-tests--xx 1))
+ (set 'bytecomp-tests--xx 2)
+ bytecomp-tests--xx)
+ (let ((aaa 1)) (set (make-local-variable 'aaa) 2) aaa)
+ (let ((bytecomp-tests--xx 1))
+ (set (make-local-variable 'bytecomp-tests--xx) 2)
+ bytecomp-tests--xx)
)
"List of expressions for cross-testing interpreted and compiled code.")
@@ -953,9 +965,6 @@ byte-compiled. Run with dynamic binding."
(bytecomp--define-warning-file-test "warn-variable-set-constant.el"
"attempt to set constant")
-(bytecomp--define-warning-file-test "warn-variable-set-nonvariable.el"
- "variable reference to nonvariable")
-
(bytecomp--define-warning-file-test "warn-variable-setq-nonvariable.el"
"attempt to set non-variable")
@@ -1007,6 +1016,10 @@ byte-compiled. Run with dynamic binding."
"defvar .foo-bar. docstring wider than .* characters" 'reverse)
(bytecomp--define-warning-file-test
+ "warn-wide-docstring-ignore-function-signature.el"
+ "defvar .foo-bar. docstring wider than .* characters" 'reverse)
+
+(bytecomp--define-warning-file-test
"warn-wide-docstring-ignore-override.el"
"defvar .foo-bar. docstring wider than .* characters" 'reverse)
diff --git a/test/lisp/emacs-lisp/cconv-tests.el b/test/lisp/emacs-lisp/cconv-tests.el
index 9904c6a969c..37470f863f3 100644
--- a/test/lisp/emacs-lisp/cconv-tests.el
+++ b/test/lisp/emacs-lisp/cconv-tests.el
@@ -347,5 +347,15 @@
(list x (funcall g closed-x) (funcall h closed-x))))))))
)
+(ert-deftest cconv-tests-interactive-closure-bug51695 ()
+ (let ((f (let ((d 51695))
+ (lambda (data)
+ (interactive (progn (setq d (1+ d)) (list d)))
+ (list (called-interactively-p 'any) data)))))
+ (should (equal (list (call-interactively f)
+ (funcall f 51695)
+ (call-interactively f))
+ '((t 51696) (nil 51695) (t 51697))))))
+
(provide 'cconv-tests)
;;; cconv-tests.el ends here
diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el b/test/lisp/emacs-lisp/cl-macs-tests.el
index 68898720d9c..f742637ee35 100644
--- a/test/lisp/emacs-lisp/cl-macs-tests.el
+++ b/test/lisp/emacs-lisp/cl-macs-tests.el
@@ -25,6 +25,8 @@
(require 'cl-macs)
(require 'edebug)
(require 'ert)
+(require 'ert-x)
+(require 'pcase)
;;;; cl-loop tests -- many adapted from Steele's CLtL2
@@ -747,4 +749,58 @@ collection clause."
;; Just make sure the forms can be instrumented.
(eval-buffer))))
+(ert-deftest cl-case-error ()
+ "Test that `cl-case' and `cl-ecase' signal an error if a t or
+`otherwise' key is misplaced."
+ (let ((text-quoting-style 'grave))
+ (dolist (form '((cl-case val (t 1) (123 2))
+ (cl-ecase val (t 1) (123 2))
+ (cl-ecase val (123 2) (t 1))))
+ (ert-info ((prin1-to-string form) :prefix "Form: ")
+ (let ((error (should-error (macroexpand form))))
+ (should (equal (cdr error)
+ '("Misplaced t or `otherwise' clause"))))))))
+
+(ert-deftest cl-case-warning ()
+ "Test that `cl-case' and `cl-ecase' warn about suspicious
+constructs."
+ (let ((text-quoting-style 'grave))
+ (pcase-dolist (`(,case . ,message)
+ `((nil . "Case nil will never match")
+ ('nil . ,(concat "Case 'nil will match `quote'. "
+ "If that's intended, write "
+ "(nil quote) instead. "
+ "Otherwise, don't quote `nil'."))
+ ('t . ,(concat "Case 't will match `quote'. "
+ "If that's intended, write "
+ "(t quote) instead. "
+ "Otherwise, don't quote `t'."))
+ ('foo . ,(concat "Case 'foo will match `quote'. "
+ "If that's intended, write "
+ "(foo quote) instead. "
+ "Otherwise, don't quote `foo'."))
+ (#'foo . ,(concat "Case #'foo will match "
+ "`function'. If that's "
+ "intended, write (foo function) "
+ "instead. Otherwise, don't "
+ "quote `foo'."))))
+ (dolist (macro '(cl-case cl-ecase))
+ (let ((form `(,macro val (,case 1))))
+ (ert-info ((prin1-to-string form) :prefix "Form: ")
+ (ert-with-message-capture messages
+ (macroexpand form)
+ (should (equal messages
+ (concat "Warning: " message "\n"))))))))))
+
+(ert-deftest cl-case-no-warning ()
+ "Test that `cl-case' and `cl-ecase' don't warn in some valid cases.
+See Bug#57915."
+ (dolist (case '(quote (quote) function (function)))
+ (dolist (macro '(cl-case cl-ecase))
+ (let ((form `(,macro val (,case 1))))
+ (ert-info ((prin1-to-string form) :prefix "Form: ")
+ (ert-with-message-capture messages
+ (macroexpand form)
+ (should (string-empty-p messages))))))))
+
;;; cl-macs-tests.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/key.pub b/test/lisp/emacs-lisp/package-resources/key.pub
index 99965723baf..241051067f0 100644
--- a/test/lisp/emacs-lisp/package-resources/key.pub
+++ b/test/lisp/emacs-lisp/package-resources/key.pub
@@ -1,17 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: Alice's OpenPGP certificate
-mQGiBGFQyDcRBACmAI6cfY3fM02vb9JtC1BS19boKXbBsDoVrD9qRf8tDFROOpO3
-ZMlbuz+O9Vnljo6Y4WZGnyeWWAMqCditMOfr1cLbux77wSrmAVgZ9exwtGzkmUhM
-xcptzKuyod8NuhghXbJgVbfJZ6HlBkk4kiWv98iJQwUBZJfjBUfIv+acjwCg4M2i
-Ifu2A3UYl9VqF7qfcDOZudEEAI7V35yfsBDnr9ndKqdGYNw0alX9BEG3KwnAe0fF
-O1jDVW12Y/bwnyyrRTrz6o1G8dj7M4XVZQb5PpT9mpNzOSZ6yxqhg+foeJwn2JkD
-vyP+kMYU7SZ/tWuMOCdzN95Ki1rf+ti7pLnSMqKx+t3vOWwQbtnsbI6RCLLwETPA
-esghA/0X3Dw7cdiE5Xq4TRaPSGViCWP4ekL2KYKqmKv6M/4f2pgFNJY7C+2SIiiP
-T62zFlIjs5tF2Df34/M5mh4Vx6E8341r55+XO++kfFWJ5QjLiydRAY6ochG9IFgB
-xyBCkCNpiby9PpKyPodedBScdMxIAe4eJR7rG/j9gFC1MypBurQnSm9obm55IFJv
-Y2tldHMgPGpvaG5ueS5yb2NrZXRzQGdmeS5vcmc+iHgEExECADgWIQRIVz1DPzm4
-REDIXNtltQG5ACv6lwUCYVDINwIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAK
-CRBltQG5ACv6l4iZAKCqldroRYH7vUzVV0Uv1NcDVcpLngCgmEoLVxGLKSwDEXNq
-qjRDzDRpReg=
-=/l51
+mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
+b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE
+ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy
+MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO
+dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4
+OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s
+E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb
+DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn
+0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=
+=iIGO
-----END PGP PUBLIC KEY BLOCK-----
diff --git a/test/lisp/emacs-lisp/package-resources/key.sec b/test/lisp/emacs-lisp/package-resources/key.sec
index 5bbac1226ae..af11bec899b 100644
--- a/test/lisp/emacs-lisp/package-resources/key.sec
+++ b/test/lisp/emacs-lisp/package-resources/key.sec
@@ -1,17 +1,16 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
+Comment: Alice's OpenPGP Transferable Secret Key
-lQG7BGFQyDcRBACmAI6cfY3fM02vb9JtC1BS19boKXbBsDoVrD9qRf8tDFROOpO3
-ZMlbuz+O9Vnljo6Y4WZGnyeWWAMqCditMOfr1cLbux77wSrmAVgZ9exwtGzkmUhM
-xcptzKuyod8NuhghXbJgVbfJZ6HlBkk4kiWv98iJQwUBZJfjBUfIv+acjwCg4M2i
-Ifu2A3UYl9VqF7qfcDOZudEEAI7V35yfsBDnr9ndKqdGYNw0alX9BEG3KwnAe0fF
-O1jDVW12Y/bwnyyrRTrz6o1G8dj7M4XVZQb5PpT9mpNzOSZ6yxqhg+foeJwn2JkD
-vyP+kMYU7SZ/tWuMOCdzN95Ki1rf+ti7pLnSMqKx+t3vOWwQbtnsbI6RCLLwETPA
-esghA/0X3Dw7cdiE5Xq4TRaPSGViCWP4ekL2KYKqmKv6M/4f2pgFNJY7C+2SIiiP
-T62zFlIjs5tF2Df34/M5mh4Vx6E8341r55+XO++kfFWJ5QjLiydRAY6ochG9IFgB
-xyBCkCNpiby9PpKyPodedBScdMxIAe4eJR7rG/j9gFC1MypBugAAn0mvGeJi+oSo
-5jXAeXBhRiTyI5WPCuK0J0pvaG5ueSBSb2NrZXRzIDxqb2hubnkucm9ja2V0c0Bn
-Znkub3JnPoh4BBMRAgA4FiEESFc9Qz85uERAyFzbZbUBuQAr+pcFAmFQyDcCGwMF
-CwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQZbUBuQAr+peImQCgqpXa6EWB+71M
-1VdFL9TXA1XKS54AoJhKC1cRiyksAxFzaqo0Q8w0aUXo
-=cyQm
+lFgEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
+b7O1u10AAP9XBeW6lzGOLx7zHH9AsUDUTb2pggYGMzd0P3ulJ2AfvQ4RtCZBbGlj
+ZSBMb3ZlbGFjZSA8YWxpY2VAb3BlbnBncC5leGFtcGxlPoiQBBMWCAA4AhsDBQsJ
+CAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE64W7X6M6deFelE5j8jFVDE9H444FAl2l
+nzoACgkQ8jFVDE9H447pKwD6A5xwUqIDprBzrHfahrImaYEZzncqb25vkLV2arYf
+a78A/R3AwtLQvjxwLDuzk4dUtUwvUYibL2sAHwj2kGaHnfICnF0EXEcE6RIKKwYB
+BAGXVQEFAQEHQEL/BiGtq0k84Km1wqQw2DIikVYrQrMttN8d7BPfnr4iAwEIBwAA
+/3/xFPG6U17rhTuq+07gmEvaFYKfxRB6sgAYiW6TMTpQEK6IeAQYFggAIBYhBOuF
+u1+jOnXhXpROY/IxVQxPR+OOBQJcRwTpAhsMAAoJEPIxVQxPR+OOWdABAMUdSzpM
+hzGs1O0RkWNQWbUzQ8nUOeD9wNbjE3zR+yfRAQDbYqvtWQKN4AQLTxVJN5X5AWyb
+Pnn+We1aTBhaGa86AQ==
+=n8OM
-----END PGP PRIVATE KEY BLOCK-----
diff --git a/test/lisp/emacs-lisp/package-resources/signed/archive-contents.sig b/test/lisp/emacs-lisp/package-resources/signed/archive-contents.sig
index b40620a0e89..db3eef9d6f7 100644
--- a/test/lisp/emacs-lisp/package-resources/signed/archive-contents.sig
+++ b/test/lisp/emacs-lisp/package-resources/signed/archive-contents.sig
Binary files differ
diff --git a/test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el.sig b/test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el.sig
index 11092411601..f6ff8e7af6c 100644
--- a/test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el.sig
+++ b/test/lisp/emacs-lisp/package-resources/signed/signed-good-1.0.el.sig
Binary files differ
diff --git a/test/lisp/emacs-lisp/package-resources/signed/update-signatures.sh b/test/lisp/emacs-lisp/package-resources/signed/update-signatures.sh
index c3e82fd1737..30e74156c01 100755
--- a/test/lisp/emacs-lisp/package-resources/signed/update-signatures.sh
+++ b/test/lisp/emacs-lisp/package-resources/signed/update-signatures.sh
@@ -25,8 +25,9 @@ TRUSTDB="./trust.db"
GPG="gpg --no-default-keyring --trustdb-name $TRUSTDB --keyring $KEYRING --yes"
rm $KEYRING
-$GPG --full-generate-key
-$GPG --export --armor > "../key.pub"
-$GPG --export-secret-keys -armor > "../key.sec"
+#$GPG --full-generate-key
+#$GPG --export --armor > "../key.pub"
+#$GPG --export-secret-keys -armor > "../key.sec"
+$GPG --import ../key.sec
$GPG --detach-sign --sign "./archive-contents"
$GPG --detach-sign --sign "./signed-good-1.0.el"
diff --git a/test/lisp/emacs-lisp/package-resources/ustar-withsub-0.1.tar b/test/lisp/emacs-lisp/package-resources/ustar-withsub-0.1.tar
new file mode 100644
index 00000000000..009c4fc420c
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/ustar-withsub-0.1.tar
Binary files differ
diff --git a/test/lisp/emacs-lisp/package-resources/v7-withsub-0.1.tar b/test/lisp/emacs-lisp/package-resources/v7-withsub-0.1.tar
new file mode 100644
index 00000000000..16c79e529f4
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/v7-withsub-0.1.tar
Binary files differ
diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el
index b903cd781ba..ffe4d7cd5fd 100644
--- a/test/lisp/emacs-lisp/package-tests.el
+++ b/test/lisp/emacs-lisp/package-tests.el
@@ -275,11 +275,31 @@ Must called from within a `tar-mode' buffer."
(let* ((pkg-el "multi-file-0.2.3.tar")
(source-file (expand-file-name pkg-el (ert-resource-directory))))
- (package-initialize)
(should-not (package-installed-p 'multie-file))
(package-install-file source-file)
(should (package-installed-p 'multi-file))
- (package-delete (cadr (assq 'multi-file package-alist))))
+ (package-delete (cadr (assq 'multi-file package-alist))))))
+
+(ert-deftest package-test-bug58367 ()
+ "Check variations in tarball formats."
+ (with-package-test (:basedir (ert-resource-directory))
+ (package-initialize)
+
+ ;; A package whose first entry is the main dir but without trailing /.
+ (let* ((pkg-el "ustar-withsub-0.1.tar")
+ (source-file (expand-file-name pkg-el (ert-resource-directory))))
+ (should-not (package-installed-p 'ustar-withsub))
+ (package-install-file source-file)
+ (should (package-installed-p 'ustar-withsub))
+ (package-delete (cadr (assq 'ustar-withsub package-alist))))
+
+ ;; A package whose first entry is a file in a subdir.
+ (let* ((pkg-el "v7-withsub-0.1.tar")
+ (source-file (expand-file-name pkg-el (ert-resource-directory))))
+ (should-not (package-installed-p 'v7-withsub))
+ (package-install-file source-file)
+ (should (package-installed-p 'v7-withsub))
+ (package-delete (cadr (assq 'v7-withsub package-alist))))
))
(ert-deftest package-test-install-file-EOLs ()
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el
index d95b35c45eb..e22f86f0447 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -592,5 +592,11 @@ Evaluate BODY for each created sequence.
(should (= (length list) 10000))
(should (= (length (seq-uniq (append list list))) 10000))))
+(ert-deftest test-seq-keep ()
+ (should (equal (seq-keep #'cl-digit-char-p '(?6 ?a ?7))
+ '(6 7)))
+ (should (equal (seq-keep #'cl-digit-char-p [?6 ?a ?7])
+ '(6 7))))
+
(provide 'seq-tests)
;;; seq-tests.el ends here
diff --git a/test/lisp/epg-resources/pubkey.asc b/test/lisp/epg-resources/pubkey.asc
index c0bf28f6200..241051067f0 100644
--- a/test/lisp/epg-resources/pubkey.asc
+++ b/test/lisp/epg-resources/pubkey.asc
@@ -1,20 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1
+Comment: Alice's OpenPGP certificate
-mI0EVRDxCAEEALcScrRmxq5N+Hh+NxPg75RJJdtEi824pwtqMlT/3wG1esmP5gNu
-ZIPVaTTSGNZkEzeYdhaLXBUe5qD+RQIQVh+MLt9nisF9nD35imyOrhHwAHnglOPx
-GdylH8nQ/tIO5p/lfUlw+iCBlPH7eZHqFJhwP0hJML4PKE8ArWG6RtsxABEBAAG0
-J0pvZSBUZXN0ZXIgKHRlc3Qga2V5KSA8am9lQGV4YW1wbGUuY29tPoi4BBMBAgAi
-BQJVEPEIAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRAoscCWMvu4GGYO
-A/0Zzoc2z/dvAtFVLh4ovKqP2qliQt2qschJHVP30hJnKT7dmJfJl7kz9mXmMfSt
-Ym0luYmeSzdeWORM9SygLRYXuDfN6G4ZPJTlsRhgnARhNzNhSx+YlcFh48Z+a5zR
-goBMn7DgYVqfU4UteZOSXMlnuA2Z5ao1qgGhVqESSJgU5riNBFUQ8QgBBADacLkK
-D0U11nmlsScxPGkrDr0aJPrG8MEaDRnKjHJKNp3XTp1psGBUpWF/ErjQAIu+psFt
-LO8owCGsg/vJM7CzTv2dVBRbrZXjIKvdq7HdivosTMaHArQBpEtSO9rmgVHO+jaQ
-q/M2oGvNEB86zo3nfTWhOgBiB32m8kttWRiuWQARAQABiJ8EGAECAAkFAlUQ8QgC
-GwwACgkQKLHAljL7uBj44AQAkMJRm7VJUryrDKFtfIfytQx/vmyU/cZcVV6IpKqP
-KhztgR+QD9czlHvQhz+y3hqtLRShu2Eyf75dNexcUvKs/lS4LIDXg5V7pWSRk9eQ
-G403muqR/NGu6+QmUx09rJl72trdaGxNkyHA7Zy7ZDGkcMvQsd3qoSNGsPR5TKes
-w7Q=
-=NMxb
+mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
+b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE
+ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy
+MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO
+dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4
+OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s
+E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb
+DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn
+0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=
+=iIGO
-----END PGP PUBLIC KEY BLOCK-----
diff --git a/test/lisp/epg-resources/seckey.asc b/test/lisp/epg-resources/seckey.asc
index 4ac7ba4a502..af11bec899b 100644
--- a/test/lisp/epg-resources/seckey.asc
+++ b/test/lisp/epg-resources/seckey.asc
@@ -1,33 +1,16 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
-Version: GnuPG v1
+Comment: Alice's OpenPGP Transferable Secret Key
-lQHYBFUQ8QgBBAC3EnK0ZsauTfh4fjcT4O+USSXbRIvNuKcLajJU/98BtXrJj+YD
-bmSD1Wk00hjWZBM3mHYWi1wVHuag/kUCEFYfjC7fZ4rBfZw9+Ypsjq4R8AB54JTj
-8RncpR/J0P7SDuaf5X1JcPoggZTx+3mR6hSYcD9ISTC+DyhPAK1hukbbMQARAQAB
-AAP9Hs9agZTobA5QOksXjt9kwqJ63gePtbwVVNz3AoobaGi39PMkRUCPZwaEEbEo
-H/CwsUMV4J5sjVtpef/A8mN4csai7NYp82mbo+dPim4p+SUtBg4Ms8ujGVcQeRQd
-1CXtIkixDu6fw4wDtNw03ZyNJOhBOXVTgAyOTSlIz3D+6n8CAMeCqEFBHQIVoQpf
-Bza4YvFtJRdfGMTix3u7Cb6y9CHGBok7uUgQAeWnzQvMGTCHc3e8iHGAYBQ88GPF
-v1TpiusCAOroRe69Aiid5JMVTjWoJ0SHKd47nIj0gQFiDfa5de0BNq9gYj7JLg+R
-EjsJbJN39z+Z9HWjIOCUOIXDvucmM1MB/iNxW1Z8mEMflEYK5rop+PDxwqUbr8uZ
-kzogw98ZdmuEuN0bheGWUiJI+0Pd8jb40zlR1KgOEMx1mZchToAJdtybMLQnSm9l
-IFRlc3RlciAodGVzdCBrZXkpIDxqb2VAZXhhbXBsZS5jb20+iLgEEwECACIFAlUQ
-8QgCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJECixwJYy+7gYZg4D/RnO
-hzbP928C0VUuHii8qo/aqWJC3aqxyEkdU/fSEmcpPt2Yl8mXuTP2ZeYx9K1ibSW5
-iZ5LN15Y5Ez1LKAtFhe4N83obhk8lOWxGGCcBGE3M2FLH5iVwWHjxn5rnNGCgEyf
-sOBhWp9ThS15k5JcyWe4DZnlqjWqAaFWoRJImBTmnQHYBFUQ8QgBBADacLkKD0U1
-1nmlsScxPGkrDr0aJPrG8MEaDRnKjHJKNp3XTp1psGBUpWF/ErjQAIu+psFtLO8o
-wCGsg/vJM7CzTv2dVBRbrZXjIKvdq7HdivosTMaHArQBpEtSO9rmgVHO+jaQq/M2
-oGvNEB86zo3nfTWhOgBiB32m8kttWRiuWQARAQABAAP7B8uNtb/DLvGoRfL+mA0Q
-REhgOJ1WpRcU6rvKYNPh8xTkKMvM+EK0nVU/znBedEpXjb0pY1WRT0uvXs2pzY2V
-YeaugyKIkdUpPWnyWoEQwI8hFvHOWmU2rNHyXLW0MY7bxcGgqv2XbkL4m7/D6VQS
-SR8hQ2CxBbW+9ov6aBMwv/UCAOW89+5xxuzkv48AVraWlMnaU0ggVOf6ht0Qa40+
-+uw2yziNlD403gAAAycoICiB/oqwslx61B2xOHn0laCKrgsCAPNpIsHRlAwWbAsq
-uCtfIQxg+C3mPXkqsNTMjeK5NjLNytrmO49NXco36zVEG6q7qz5Zj9d9IPYoGOSa
-I+dQZ6sB/RKF5aonR5/e7IHJgc8BG7I0yiya4llE0AB9ghnRI/3uHwnCBnmo/32a
-n4+rQkx6vm+rg3JA/09Gi7W4R9SwV+ane4ifBBgBAgAJBQJVEPEIAhsMAAoJECix
-wJYy+7gY+OAEAJDCUZu1SVK8qwyhbXyH8rUMf75slP3GXFVeiKSqjyoc7YEfkA/X
-M5R70Ic/st4arS0UobthMn++XTXsXFLyrP5UuCyA14OVe6VkkZPXkBuNN5rqkfzR
-ruvkJlMdPayZe9ra3WhsTZMhwO2cu2QxpHDL0LHd6qEjRrD0eUynrMO0
-=iCIm
+lFgEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
+b7O1u10AAP9XBeW6lzGOLx7zHH9AsUDUTb2pggYGMzd0P3ulJ2AfvQ4RtCZBbGlj
+ZSBMb3ZlbGFjZSA8YWxpY2VAb3BlbnBncC5leGFtcGxlPoiQBBMWCAA4AhsDBQsJ
+CAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE64W7X6M6deFelE5j8jFVDE9H444FAl2l
+nzoACgkQ8jFVDE9H447pKwD6A5xwUqIDprBzrHfahrImaYEZzncqb25vkLV2arYf
+a78A/R3AwtLQvjxwLDuzk4dUtUwvUYibL2sAHwj2kGaHnfICnF0EXEcE6RIKKwYB
+BAGXVQEFAQEHQEL/BiGtq0k84Km1wqQw2DIikVYrQrMttN8d7BPfnr4iAwEIBwAA
+/3/xFPG6U17rhTuq+07gmEvaFYKfxRB6sgAYiW6TMTpQEK6IeAQYFggAIBYhBOuF
+u1+jOnXhXpROY/IxVQxPR+OOBQJcRwTpAhsMAAoJEPIxVQxPR+OOWdABAMUdSzpM
+hzGs1O0RkWNQWbUzQ8nUOeD9wNbjE3zR+yfRAQDbYqvtWQKN4AQLTxVJN5X5AWyb
+Pnn+We1aTBhaGa86AQ==
+=n8OM
-----END PGP PRIVATE KEY BLOCK-----
diff --git a/test/lisp/epg-tests.el b/test/lisp/epg-tests.el
index 65aaafd9f18..dca6f337647 100644
--- a/test/lisp/epg-tests.el
+++ b/test/lisp/epg-tests.el
@@ -101,16 +101,15 @@
(ert-deftest epg-decrypt-1 ()
:expected-result (if (getenv "EMACS_HYDRA_CI") :failed :passed) ; fixme
(with-epg-tests (:require-passphrase t)
- (with-temp-file (expand-file-name "gpg.conf" epg-tests-home-directory)
- (insert "ignore-mdc-error"))
(should (equal "test"
(epg-decrypt-string epg-tests-context "\
-----BEGIN PGP MESSAGE-----
-Version: GnuPG v2
-jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA==
-=U8z7
------END PGP MESSAGE-----")))))
+jA0ECQMCdW8+qtS9Tin/0jUBO1/9Oz69BWPmtFKEeBM62WpFP4o1+bNzdxogdyeg
++WTt292OD0yV85m5UqvLgp4ttVUmAw==
+=K5Eh
+-----END PGP MESSAGE-----
+")))))
(ert-deftest epg-roundtrip-1 ()
:expected-result (if (getenv "EMACS_HYDRA_CI") :failed :passed) ; fixme
@@ -123,7 +122,7 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA==
(with-epg-tests (:require-passphrase t
:require-public-key t
:require-secret-key t)
- (let* ((recipients (epg-list-keys epg-tests-context "joe@example.com"))
+ (let* ((recipients (epg-list-keys epg-tests-context "alice@openpgp.example"))
(cipher (epg-encrypt-string epg-tests-context "public key"
recipients nil t)))
(should (equal "public key"
@@ -135,7 +134,7 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA==
:require-secret-key t)
(let (signature verify-result)
(setf (epg-context-signers epg-tests-context)
- (epg-list-keys epg-tests-context "joe@example.com"))
+ (epg-list-keys epg-tests-context "alice@openpgp.example"))
(setq signature (epg-sign-string epg-tests-context "signed" t))
(epg-verify-string epg-tests-context signature "signed")
(setq verify-result (epg-context-result-for context 'verify))
@@ -148,7 +147,7 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA==
:require-secret-key t)
(let (signature verify-result)
(setf (epg-context-signers epg-tests-context)
- (epg-list-keys epg-tests-context "joe@example.com"))
+ (epg-list-keys epg-tests-context "alice@openpgp.example"))
(setq signature (epg-sign-string epg-tests-context "clearsigned" 'clear))
;; Clearsign signature always ends with a new line.
(should (equal "clearsigned\n"
@@ -163,7 +162,7 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA==
:require-secret-key t)
(let (signature verify-result)
(setf (epg-context-signers epg-tests-context)
- (epg-list-keys epg-tests-context "joe@example.com"))
+ (epg-list-keys epg-tests-context "alice@openpgp.example"))
(setq signature (epg-sign-string epg-tests-context "normal signed"))
(should (equal "normal signed"
(epg-verify-string epg-tests-context signature)))
diff --git a/test/lisp/erc/erc-match-tests.el b/test/lisp/erc/erc-match-tests.el
new file mode 100644
index 00000000000..cd7598703b5
--- /dev/null
+++ b/test/lisp/erc/erc-match-tests.el
@@ -0,0 +1,193 @@
+;;; erc-match-tests.el --- Tests for erc-match. -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Code:
+
+(require 'ert-x)
+(require 'erc-match)
+
+
+(ert-deftest erc-add-entry-to-list ()
+ (let ((erc-pals '("z"))
+ (erc-match-quote-when-adding 'ask))
+
+ (ert-info ("Default (ask)")
+ (ert-simulate-keys "\t\ry\r"
+ (erc-add-entry-to-list 'erc-pals "?" '((".")) nil)
+ (should (equal (pop erc-pals) "\\.")))
+
+ (ert-info ("Inverted")
+ (ert-simulate-keys "\t\ry\r"
+ (erc-add-entry-to-list 'erc-pals "?" '((".")) nil)
+ (should (equal (pop erc-pals) "\\."))))
+
+ (ert-info ("Skipped")
+ (ert-simulate-keys "\t\r"
+ (erc-add-entry-to-list 'erc-pals "?" '(("x")) nil)
+ (should (equal (pop erc-pals) "x")))))
+
+ (ert-info ("Verbatim")
+ (setq erc-match-quote-when-adding nil)
+ (ert-simulate-keys "\t\r"
+ (erc-add-entry-to-list 'erc-pals "?" '((".")) nil)
+ (should (equal (pop erc-pals) ".")))
+
+ (ert-info ("Inverted")
+ (ert-simulate-keys "\t\r"
+ (erc-add-entry-to-list 'erc-pals "?" '((".")) t)
+ (should (equal (pop erc-pals) "\\.")))))
+
+ (ert-info ("Quoted")
+ (setq erc-match-quote-when-adding t)
+ (ert-simulate-keys "\t\r"
+ (erc-add-entry-to-list 'erc-pals "?" '((".")) nil)
+ (should (equal (pop erc-pals) "\\.")))
+
+ (ert-info ("Inverted")
+ (ert-simulate-keys "\t\r"
+ (erc-add-entry-to-list 'erc-pals "?" '((".")) t)
+ (should (equal (pop erc-pals) ".")))))
+
+ (should (equal erc-pals '("z")))))
+
+(ert-deftest erc-pals ()
+ (with-temp-buffer
+ (setq erc-server-process (start-process "true" (current-buffer) "true")
+ erc-server-users (make-hash-table :test #'equal))
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (erc-add-server-user "FOO[m]" (make-erc-server-user :nickname "foo[m]"))
+ (erc-add-server-user "tester" (make-erc-server-user :nickname "tester"))
+
+ (let ((erc-match-quote-when-adding t)
+ erc-pals calls rvs)
+ (cl-letf (((symbol-function 'completing-read)
+ (lambda (&rest r) (push r calls) (pop rvs))))
+
+ (ert-info ("`erc-add-pal'")
+ (push "foo[m]" rvs)
+ (ert-simulate-command '(erc-add-pal))
+ (should (equal (cadr (pop calls)) '(("tester") ("foo[m]"))))
+ (should (equal erc-pals '("foo\\[m]"))))
+
+ (ert-info ("`erc-match-pal-p'")
+ (should (erc-match-pal-p "FOO[m]!~u@example.net" nil)))
+
+ (ert-info ("`erc-delete-pal'")
+ (push "foo\\[m]" rvs)
+ (ert-simulate-command '(erc-delete-pal))
+ (should (equal (cadr (pop calls)) '(("foo\\[m]"))))
+ (should-not erc-pals))
+
+ (ert-info ("`erc-add-pal' verbatim")
+ (push "foo[m]" rvs)
+ (ert-simulate-command '(erc-add-pal (4)))
+ (should (equal (cadr (pop calls)) '(("tester") ("foo[m]"))))
+ (should (equal erc-pals '("foo[m]"))))))))
+
+(ert-deftest erc-fools ()
+ (with-temp-buffer
+ (setq erc-server-process (start-process "true" (current-buffer) "true")
+ erc-server-users (make-hash-table :test #'equal))
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (erc-add-server-user "FOO[m]" (make-erc-server-user :nickname "foo[m]"))
+ (erc-add-server-user "tester" (make-erc-server-user :nickname "tester"))
+
+ (let ((erc-match-quote-when-adding t)
+ erc-fools calls rvs)
+ (cl-letf (((symbol-function 'completing-read)
+ (lambda (&rest r) (push r calls) (pop rvs))))
+
+ (ert-info ("`erc-add-fool'")
+ (push "foo[m]" rvs)
+ (ert-simulate-command '(erc-add-fool))
+ (should (equal (cadr (pop calls)) '(("tester") ("foo[m]"))))
+ (should (equal erc-fools '("foo\\[m]"))))
+
+ (ert-info ("`erc-match-fool-p'")
+ (should (erc-match-fool-p "FOO[m]!~u@example.net" ""))
+ (should (erc-match-fool-p "tester!~u@example.net" "FOO[m]: die")))
+
+ (ert-info ("`erc-delete-fool'")
+ (push "foo\\[m]" rvs)
+ (ert-simulate-command '(erc-delete-fool))
+ (should (equal (cadr (pop calls)) '(("foo\\[m]"))))
+ (should-not erc-fools))
+
+ (ert-info ("`erc-add-fool' verbatim")
+ (push "foo[m]" rvs)
+ (ert-simulate-command '(erc-add-fool (4)))
+ (should (equal (cadr (pop calls)) '(("tester") ("foo[m]"))))
+ (should (equal erc-fools '("foo[m]"))))))))
+
+(ert-deftest erc-keywords ()
+ (let ((erc-match-quote-when-adding t)
+ erc-keywords calls rvs)
+ (cl-letf (((symbol-function 'completing-read)
+ (lambda (&rest r) (push r calls) (pop rvs))))
+
+ (ert-info ("`erc-add-keyword'")
+ (push "[cit. needed]" rvs)
+ (ert-simulate-command '(erc-add-keyword))
+ (should (equal (cadr (pop calls)) nil))
+ (should (equal erc-keywords '("\\[cit\\. needed]"))))
+
+ (ert-info ("`erc-match-keyword-p'")
+ (should (erc-match-keyword-p nil "is pretty [cit. needed]")))
+
+ (ert-info ("`erc-delete-keyword'")
+ (push "\\[cit\\. needed]" rvs)
+ (ert-simulate-command '(erc-delete-keyword))
+ (should (equal (cadr (pop calls)) '(("\\[cit\\. needed]"))))
+ (should-not erc-keywords))
+
+ (ert-info ("`erc-add-keyword' verbatim")
+ (push "[...]" rvs)
+ (ert-simulate-command '(erc-add-keyword (4)))
+ (should (equal (cadr (pop calls)) nil))
+ (should (equal erc-keywords '("[...]")))))))
+
+(ert-deftest erc-dangerous-hosts ()
+ (let ((erc-match-quote-when-adding t)
+ erc-dangerous-hosts calls rvs)
+ (cl-letf (((symbol-function 'completing-read)
+ (lambda (&rest r) (push r calls) (pop rvs))))
+
+ (ert-info ("`erc-add-dangerous-host'")
+ (push "example.net" rvs)
+ (ert-simulate-command '(erc-add-dangerous-host))
+ (should (equal (cadr (pop calls)) nil))
+ (should (equal erc-dangerous-hosts '("example\\.net"))))
+
+ (ert-info ("`erc-match-dangerous-host-p'")
+ (should (erc-match-dangerous-host-p "FOO[m]!~u@example.net" nil)))
+
+ (ert-info ("`erc-delete-dangerous-host'")
+ (push "example\\.net" rvs)
+ (ert-simulate-command '(erc-delete-dangerous-host))
+ (should (equal (cadr (pop calls)) '(("example\\.net"))))
+ (should-not erc-dangerous-hosts))
+
+ (ert-info ("`erc-add-dangerous-host' verbatim")
+ (push "example.net" rvs)
+ (ert-simulate-command '(erc-add-dangerous-host (4)))
+ (should (equal (cadr (pop calls)) nil))
+ (should (equal erc-dangerous-hosts '("example.net")))))))
+
+;;; erc-match-tests.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-reconnect.el b/test/lisp/erc/erc-scenarios-base-reconnect.el
index 30d692058d6..49298dc5942 100644
--- a/test/lisp/erc/erc-scenarios-base-reconnect.el
+++ b/test/lisp/erc/erc-scenarios-base-reconnect.el
@@ -99,10 +99,11 @@
(funcall test)
+ ;; A manual /JOIN command tells ERC we're done auto-reconnecting
(with-current-buffer "FooNet" (erc-cmd-JOIN "#spam"))
- (erc-d-t-wait-for 5 "Channel #spam shown when autojoined"
- (eq (window-buffer) (get-buffer "#spam")))
+ (erc-d-t-ensure-for 1 "Newly joined chan ignores `erc-reconnect-display'"
+ (not (eq (window-buffer) (get-buffer "#spam"))))
(ert-info ("Wait for auto reconnect")
(with-current-buffer erc-server-buffer
@@ -114,43 +115,43 @@
(with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))
(funcall expect 10 "her elves come here anon")))))
-(ert-deftest erc-scenarios-base-reconnect-options--default ()
+(ert-deftest erc-scenarios-base-reconnect-options--buffer ()
:tags '(:expensive-test)
- (should (eq erc-join-buffer 'buffer))
+ (should (eq erc-join-buffer 'bury))
(should-not erc-reconnect-display)
;; FooNet (the server buffer) is not switched to because it's
;; already current (but not shown) when `erc-open' is called. See
;; related conditional guard towards the end of that function.
- (erc-scenarios-common--base-reconnect-options
- (lambda ()
- (pop-to-buffer-same-window "*Messages*")
+ (let ((erc-reconnect-display 'buffer))
+ (erc-scenarios-common--base-reconnect-options
+ (lambda ()
+ (pop-to-buffer-same-window "*Messages*")
- (erc-d-t-ensure-for 1 "Server buffer not shown"
- (not (eq (window-buffer) (get-buffer "FooNet"))))
+ (erc-d-t-ensure-for 1 "Server buffer not shown"
+ (not (eq (window-buffer) (get-buffer "FooNet"))))
- (erc-d-t-wait-for 5 "Channel #chan shown when autojoined"
- (eq (window-buffer) (get-buffer "#chan"))))))
+ (erc-d-t-wait-for 5 "Channel #chan shown when autojoined"
+ (eq (window-buffer) (get-buffer "#chan")))))))
-(ert-deftest erc-scenarios-base-reconnect-options--bury ()
+(ert-deftest erc-scenarios-base-reconnect-options--default ()
:tags '(:expensive-test)
- (should (eq erc-join-buffer 'buffer))
+ (should (eq erc-join-buffer 'bury))
(should-not erc-reconnect-display)
- (let ((erc-reconnect-display 'bury))
- (erc-scenarios-common--base-reconnect-options
+ (erc-scenarios-common--base-reconnect-options
- (lambda ()
- (pop-to-buffer-same-window "*Messages*")
+ (lambda ()
+ (pop-to-buffer-same-window "*Messages*")
- (erc-d-t-ensure-for 1 "Server buffer not shown"
- (not (eq (window-buffer) (get-buffer "FooNet"))))
+ (erc-d-t-ensure-for 1 "Server buffer not shown"
+ (not (eq (window-buffer) (get-buffer "FooNet"))))
- (erc-d-t-ensure-for 3 "Channel #chan not shown"
- (not (eq (window-buffer) (get-buffer "#chan"))))
+ (erc-d-t-ensure-for 3 "Channel #chan not shown"
+ (not (eq (window-buffer) (get-buffer "#chan"))))
- (eq (window-buffer) (messages-buffer))))))
+ (eq (window-buffer) (messages-buffer)))))
;; Upon reconnecting, playback for channel and target buffers is
;; routed correctly. Autojoin is irrelevant here, but for the
diff --git a/test/lisp/erc/erc-scenarios-base-reuse-buffers.el b/test/lisp/erc/erc-scenarios-base-reuse-buffers.el
index f134f3ffb69..8e7e939d046 100644
--- a/test/lisp/erc/erc-scenarios-base-reuse-buffers.el
+++ b/test/lisp/erc/erc-scenarios-base-reuse-buffers.el
@@ -131,43 +131,38 @@ Adapted from scenario clash-of-chans/uniquify described in Bug#48598:
(get-buffer (format "127.0.0.1:%d/127.0.0.1" port)))
(server-buffer-bar
(get-buffer (format "127.0.0.1:%d/127.0.0.1<2>" port)))
- (chan-buffer-foo (get-buffer "#chan/127.0.0.1"))
- (chan-buffer-bar (get-buffer "#chan/127.0.0.1<2>"))
- (server-process-foo (with-current-buffer server-buffer-foo
- erc-server-process))
- (server-process-bar (with-current-buffer server-buffer-bar
- erc-server-process)))
+ (server-process-foo
+ (buffer-local-value 'erc-server-process server-buffer-foo))
+ (server-process-bar
+ (buffer-local-value 'erc-server-process server-buffer-bar)))
(ert-info ("Unique #chan buffers exist")
- (let ((chan-bufs (erc-scenarios-common-buflist "#chan"))
- (known (list chan-buffer-bar chan-buffer-foo)))
- (should (memq (pop chan-bufs) known))
- (should (memq (pop chan-bufs) known))
- (should-not chan-bufs)))
+ (erc-d-t-wait-for 3 (get-buffer "#chan/127.0.0.1<2>"))
+ (erc-d-t-wait-for 3 (get-buffer "#chan/127.0.0.1")))
(ert-info ("#chan@foonet is exclusive and not contaminated")
- (with-current-buffer chan-buffer-foo
+ (with-current-buffer "#chan/127.0.0.1"
(funcall expect 1 "<bob>")
(erc-d-t-absent-for 0.1 "<joe>")
(funcall expect 1 "strength to climb")
(should (eq erc-server-process server-process-foo))))
(ert-info ("#chan@barnet is exclusive and not contaminated")
- (with-current-buffer chan-buffer-bar
+ (with-current-buffer "#chan/127.0.0.1<2>"
(funcall expect 1 "<joe>")
(erc-d-t-absent-for 0.1 "<bob>")
(funcall expect 1 "the loudest noise")
(should (eq erc-server-process server-process-bar))))
(ert-info ("Part #chan@foonet")
- (with-current-buffer chan-buffer-foo
+ (with-current-buffer "#chan/127.0.0.1"
(erc-d-t-search-for 1 "shake my sword")
(erc-cmd-PART "#chan")
(funcall expect 3 "You have left channel #chan")
(erc-cmd-JOIN "#chan")))
(ert-info ("Part #chan@barnet")
- (with-current-buffer chan-buffer-bar
+ (with-current-buffer "#chan/127.0.0.1<2>"
(funcall expect 10 "Arm it in rags")
(should (erc-get-channel-user (erc-current-nick)))
(erc-cmd-PART "#chan")
@@ -179,7 +174,7 @@ Adapted from scenario clash-of-chans/uniquify described in Bug#48598:
(get-buffer "#chan/127.0.0.1<3>"))
(ert-info ("Activity continues in new, <n>-suffixed #chan@foonet buffer")
- (with-current-buffer chan-buffer-foo
+ (with-current-buffer "#chan/127.0.0.1"
(should-not (erc-get-channel-user (erc-current-nick))))
(with-current-buffer "#chan/127.0.0.1<3>"
(should (erc-get-channel-user (erc-current-nick)))
@@ -194,7 +189,7 @@ Adapted from scenario clash-of-chans/uniquify described in Bug#48598:
(get-buffer "#chan/127.0.0.1<4>"))
(ert-info ("Activity continues in new, <n>-suffixed #chan@barnet buffer")
- (with-current-buffer chan-buffer-bar
+ (with-current-buffer "#chan/127.0.0.1<2>"
(should-not (erc-get-channel-user (erc-current-nick))))
(with-current-buffer "#chan/127.0.0.1<4>"
(funcall expect 2 "You have joined channel #chan")
@@ -221,12 +216,12 @@ Adapted from scenario clash-of-chans/uniquify described in Bug#48598:
(ert-info ("Buffers are exempt from shortening")
(kill-buffer "#chan/127.0.0.1<4>")
(kill-buffer "#chan/127.0.0.1<3>")
- (kill-buffer chan-buffer-bar)
+ (kill-buffer "#chan/127.0.0.1<2>")
(should-not (get-buffer "#chan"))
- (should chan-buffer-foo))))
+ (should (get-buffer "#chan/127.0.0.1")))))
(ert-deftest erc-scenarios-base-reuse-buffers-channel-buffers--disabled ()
- :tags '(:expensive-test :unstable)
+ :tags '(:expensive-test)
(with-suppressed-warnings ((obsolete erc-reuse-buffers))
(should erc-reuse-buffers)
(let ((erc-scenarios-common-dialog "base/reuse-buffers/channel")
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 55efe2fd2d9..b2ed29e80ec 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -522,7 +522,7 @@
(erc-send-current-line)
(should (ring-p erc-input-ring))
(should (zerop (ring-member erc-input-ring "/one"))) ; equal
- (should (save-excursion (forward-line -1) (goto-char (pos-bol))
+ (should (save-excursion (forward-line -1)
(looking-at-p "[*]+ echo: one")))
(should-not erc-input-ring-index)
(erc-bol)
diff --git a/test/lisp/erc/resources/base/assoc/samenet/chester.eld b/test/lisp/erc/resources/base/assoc/samenet/chester.eld
index f1aed2836c7..0132de677cb 100644
--- a/test/lisp/erc/resources/base/assoc/samenet/chester.eld
+++ b/test/lisp/erc/resources/base/assoc/samenet/chester.eld
@@ -1,5 +1,5 @@
;; -*- mode: lisp-data; -*-
-((pass 1 "PASS :changeme"))
+((pass 10 "PASS :changeme"))
((nick 1 "NICK chester"))
((user 1 "USER user 0 * :chester")
(0 ":irc.foonet.org 001 chester :Welcome to the foonet IRC Network chester")
diff --git a/test/lisp/erc/resources/base/assoc/samenet/tester.eld b/test/lisp/erc/resources/base/assoc/samenet/tester.eld
index cd9cacbe5dc..995fab00f7d 100644
--- a/test/lisp/erc/resources/base/assoc/samenet/tester.eld
+++ b/test/lisp/erc/resources/base/assoc/samenet/tester.eld
@@ -1,5 +1,5 @@
;; -*- mode: lisp-data; -*-
-((pass 1 "PASS :changeme"))
+((pass 10 "PASS :changeme"))
((nick 1 "NICK tester"))
((user 1 "USER user 0 * :tester")
(0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
diff --git a/test/lisp/erc/resources/base/assoc/samenet/tester2.eld b/test/lisp/erc/resources/base/assoc/samenet/tester2.eld
index 67c3a94a262..33a05fe2611 100644
--- a/test/lisp/erc/resources/base/assoc/samenet/tester2.eld
+++ b/test/lisp/erc/resources/base/assoc/samenet/tester2.eld
@@ -1,5 +1,5 @@
;; -*- mode: lisp-data; -*-
-((pass 1 "PASS :changeme"))
+((pass 10 "PASS :changeme"))
((nick 1 "NICK tester"))
((user 1 "USER user 0 * :tester")
(0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
diff --git a/test/lisp/erc/resources/base/netid/samenet/chester.eld b/test/lisp/erc/resources/base/netid/samenet/chester.eld
index 8c2448733ce..7b4bfee9c9a 100644
--- a/test/lisp/erc/resources/base/netid/samenet/chester.eld
+++ b/test/lisp/erc/resources/base/netid/samenet/chester.eld
@@ -1,5 +1,5 @@
;; -*- mode: lisp-data; -*-
-((pass 1 "PASS :changeme"))
+((pass 10 "PASS :changeme"))
((nick 1 "NICK chester"))
((user 1 "USER user 0 * :chester")
(0 ":irc.foonet.org 001 chester :Welcome to the foonet IRC Network chester")
diff --git a/test/lisp/erc/resources/base/netid/samenet/tester.eld b/test/lisp/erc/resources/base/netid/samenet/tester.eld
index 76312a7a14a..f41b041db4b 100644
--- a/test/lisp/erc/resources/base/netid/samenet/tester.eld
+++ b/test/lisp/erc/resources/base/netid/samenet/tester.eld
@@ -1,5 +1,5 @@
;; -*- mode: lisp-data; -*-
-((pass 1 "PASS :changeme"))
+((pass 10 "PASS :changeme"))
((nick 1 "NICK tester"))
((user 1 "USER user 0 * :tester")
(0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
diff --git a/test/lisp/erc/resources/erc-d/erc-d-tests.el b/test/lisp/erc/resources/erc-d/erc-d-tests.el
index 357bc48b088..a4befd96b5e 100644
--- a/test/lisp/erc/resources/erc-d/erc-d-tests.el
+++ b/test/lisp/erc/resources/erc-d/erc-d-tests.el
@@ -673,7 +673,7 @@ nonzero for this to work."
(cadr (pop errors))))))
(ert-deftest erc-d-run-linger ()
- :tags '(:expensive-test)
+ :tags '(:unstable :expensive-test)
(erc-d-tests-with-server (dumb-s _) linger
(with-current-buffer (erc-d-t-wait-for 6 (get-buffer "#chan"))
(erc-d-t-search-for 2 "hey"))
@@ -683,7 +683,7 @@ nonzero for this to work."
(erc-d-t-search-for 3 "Lingered for 1.00 seconds"))))
(ert-deftest erc-d-run-linger-fail ()
- :tags '(:expensive-test)
+ :tags '(:unstable :expensive-test)
(let ((erc-server-flood-penalty 0.1)
errors)
(erc-d-tests-with-failure-spy
@@ -696,7 +696,7 @@ nonzero for this to work."
(should (string-match-p "Match failed.*hi" (cadr (pop errors))))))
(ert-deftest erc-d-run-linger-direct ()
- :tags '(:expensive-test)
+ :tags '(:unstable :expensive-test)
(let* ((dumb-server (erc-d-run "localhost" t
'linger-multi-a 'linger-multi-b))
(port (process-contact dumb-server :service))
diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el
index bebc57d3592..cb5b1766bb5 100644
--- a/test/lisp/eshell/esh-var-tests.el
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -105,9 +105,11 @@
(ert-deftest esh-var-test/interp-var-assoc ()
"Interpolate alist variable with index"
- (let ((eshell-test-value '(("foo" . 1))))
+ (let ((eshell-test-value '(("foo" . 1) (bar . 2))))
(eshell-command-result-equal "echo $eshell-test-value[foo]"
- 1)))
+ 1)
+ (eshell-command-result-equal "echo $eshell-test-value[#'bar]"
+ 2)))
(ert-deftest esh-var-test/interp-var-length-list ()
"Interpolate length of list variable"
@@ -257,9 +259,11 @@ inside double-quotes"
(ert-deftest esh-var-test/quoted-interp-var-assoc ()
"Interpolate alist variable with index inside double-quotes"
- (let ((eshell-test-value '(("foo" . 1))))
+ (let ((eshell-test-value '(("foo" . 1) (bar . 2))))
(eshell-command-result-equal "echo \"$eshell-test-value[foo]\""
- "1")))
+ "1")
+ (eshell-command-result-equal "echo \"$eshell-test-value[#'bar]\""
+ "2")))
(ert-deftest esh-var-test/quoted-interp-var-length-list ()
"Interpolate length of list variable inside double-quotes"
diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el
index 2d147e900d7..d82e2dae7aa 100644
--- a/test/lisp/filenotify-tests.el
+++ b/test/lisp/filenotify-tests.el
@@ -137,6 +137,10 @@ Return nil when any other file notification watch is still active."
(defun file-notify--test-cleanup ()
"Cleanup after a test."
+ ;; (when (getenv "EMACS_EMBA_CI")
+ ;; (dolist (buf (tramp-list-tramp-buffers))
+ ;; (message ";; %s\n%s" buf (tramp-get-buffer-string buf))
+ ;; (kill-buffer buf)))
(file-notify-rm-all-watches)
(ignore-errors
@@ -173,6 +177,7 @@ Return nil when any other file notification watch is still active."
(setq file-notify-debug nil
password-cache-expiry nil
+ ;; tramp-verbose (if (getenv "EMACS_EMBA_CI") 10 0)
tramp-verbose 0
;; When the remote user id is 0, Tramp refuses unsafe temporary files.
tramp-allow-unsafe-temporary-files
@@ -1571,6 +1576,136 @@ the file watch."
(file-notify--deftest-remote file-notify-test10-sufficient-resources
"Check `file-notify-test10-sufficient-resources' for remote files.")
+(ert-deftest file-notify-test11-symlinks ()
+ "Check that file notification do not follow symbolic links."
+ :tags '(:expensive-test)
+ (skip-unless (file-notify--test-local-enabled))
+ ;; This test does not work for kqueue (yet).
+ (skip-unless (not (string-equal (file-notify--test-library) "kqueue")))
+
+ (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
+ file-notify--test-tmpfile1 (file-notify--test-make-temp-name))
+
+ ;; Symlink a file.
+ (unwind-protect
+ (progn
+ (write-region "any text" nil file-notify--test-tmpfile1 nil 'no-message)
+ ;; Some systems, like MS Windows w/o sufficient privileges, do
+ ;; not allow creation of symbolic links.
+ (condition-case nil
+ (make-symbolic-link
+ file-notify--test-tmpfile1 file-notify--test-tmpfile)
+ (error (ert-skip "`make-symbolic-link' not supported")))
+ (should
+ (setq file-notify--test-desc
+ (file-notify--test-add-watch
+ file-notify--test-tmpfile
+ '(attribute-change change) #'file-notify--test-event-handler)))
+ (should (file-notify-valid-p file-notify--test-desc))
+
+ ;; Writing to either the symlink or the target should not
+ ;; raise any event.
+ (file-notify--test-with-actions nil
+ (write-region
+ "another text" nil file-notify--test-tmpfile nil 'no-message)
+ (write-region
+ "another text" nil file-notify--test-tmpfile1 nil 'no-message))
+ ;; Sanity check.
+ (file-notify--test-wait-for-events
+ (file-notify--test-timeout)
+ (not (input-pending-p)))
+ (should-not file-notify--test-events)
+
+ ;; Changing timestamp of the target should not raise any
+ ;; event. We don't use `nofollow'.
+ (file-notify--test-with-actions nil
+ (set-file-times file-notify--test-tmpfile1 '(0 0))
+ (set-file-times file-notify--test-tmpfile '(0 0)))
+ ;; Sanity check.
+ (file-notify--test-wait-for-events
+ (file-notify--test-timeout)
+ (not (input-pending-p)))
+ (should-not file-notify--test-events)
+
+ ;; Changing timestamp of the symlink shows the event.
+ (file-notify--test-with-actions
+ (cond
+ ;; w32notify does not distinguish between `changed' and
+ ;; `attribute-changed'.
+ ((string-equal (file-notify--test-library) "w32notify")
+ '(changed))
+ ;; GFam{File,Directory}Monitor, GKqueueFileMonitor and
+ ;; GPollFileMonitor do not report the `attribute-changed'
+ ;; event.
+ ((memq (file-notify--test-monitor)
+ '(GFamFileMonitor GFamDirectoryMonitor
+ GKqueueFileMonitor GPollFileMonitor))
+ '())
+ (t '(attribute-changed)))
+ (set-file-times file-notify--test-tmpfile '(0 0) 'nofollow))
+
+ ;; Deleting the target should not raise any event.
+ (file-notify--test-with-actions nil
+ (delete-file file-notify--test-tmpfile1)
+ (delete-file file-notify--test-tmpfile))
+ ;; Sanity check.
+ (file-notify--test-wait-for-events
+ (file-notify--test-timeout)
+ (not (input-pending-p)))
+ (should-not file-notify--test-events)
+
+ ;; The environment shall be cleaned up.
+ (file-notify-rm-watch file-notify--test-desc)
+ (file-notify--test-cleanup-p))
+
+ ;; Cleanup.
+ (file-notify--test-cleanup))
+
+ (setq file-notify--test-tmpfile1 (file-notify--test-make-temp-name)
+ file-notify--test-tmpfile (file-notify--test-make-temp-name))
+
+ ;; Symlink a directory.
+ (unwind-protect
+ (let ((tmpfile (expand-file-name "foo" file-notify--test-tmpfile))
+ (tmpfile1 (expand-file-name "foo" file-notify--test-tmpfile1)))
+ (make-directory file-notify--test-tmpfile1)
+ (make-symbolic-link file-notify--test-tmpfile1 file-notify--test-tmpfile)
+ (write-region "any text" nil tmpfile1 nil 'no-message)
+ (should
+ (setq file-notify--test-desc
+ (file-notify--test-add-watch
+ file-notify--test-tmpfile
+ '(attribute-change change) #'file-notify--test-event-handler)))
+ (should (file-notify-valid-p file-notify--test-desc))
+
+ ;; None of the actions on a file in the symlinked directory
+ ;; will be reported.
+ (file-notify--test-with-actions nil
+ (write-region "another text" nil tmpfile nil 'no-message)
+ (write-region "another text" nil tmpfile1 nil 'no-message)
+ (set-file-times tmpfile '(0 0))
+ (set-file-times tmpfile '(0 0) 'nofollow)
+ (set-file-times tmpfile1 '(0 0))
+ (set-file-times tmpfile1 '(0 0) 'nofollow)
+ (delete-file tmpfile)
+ (delete-file tmpfile1))
+ ;; Sanity check.
+ (file-notify--test-wait-for-events
+ (file-notify--test-timeout)
+ (not (input-pending-p)))
+ (should-not file-notify--test-events)
+
+ ;; The environment shall be cleaned up.
+ (delete-directory file-notify--test-tmpdir 'recursive)
+ (file-notify-rm-watch file-notify--test-desc)
+ (file-notify--test-cleanup-p))
+
+ ;; Cleanup.
+ (file-notify--test-cleanup)))
+
+(file-notify--deftest-remote file-notify-test11-symlinks
+ "Check `file-notify-test11-symlinks' for remote files.")
+
(defun file-notify-test-all (&optional interactive)
"Run all tests for \\[file-notify]."
(interactive "p")
diff --git a/test/lisp/format-spec-tests.el b/test/lisp/format-spec-tests.el
index 4a3cc74c334..bd493ae1d71 100644
--- a/test/lisp/format-spec-tests.el
+++ b/test/lisp/format-spec-tests.el
@@ -148,6 +148,17 @@
(format-spec fmt '((?b . "asd") (?a . "fgh")))
#("fgh%asdasd" 0 3 (a b) 3 4 (c d) 7 10 (e f))))))
+(ert-deftest format-spec/function ()
+ (let* (called
+ (spec `((?a . "foo")
+ (?f . ,(lambda ()
+ (setq called t)
+ "bar")))))
+ (should (equal (format-spec "%a" spec) "foo"))
+ (should-not called)
+ (should (equal (format-spec "%f" spec) "bar"))
+ (should called)))
+
(ert-deftest format-spec-unknown ()
(should-error (format-spec "foo %b %z zot" '((?b . "bar"))))
(should-error (format-spec "foo %b %%%z zot" '((?b . "bar"))))
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/0062E2DBC6D6848AE88BCE181CC1938F2FAC816C.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/0062E2DBC6D6848AE88BCE181CC1938F2FAC816C.key
new file mode 100644
index 00000000000..6f1e145295b
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/0062E2DBC6D6848AE88BCE181CC1938F2FAC816C.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #40C5151DC16303D3BD25F10C092E411CC3D65F7DF30DD8DDBDB17771EED64F8874#)
+ (d #7AA2EEE8EC08C2B41C4AAD9484D2ED8F6C630392892322827901B37EE3973E68#)
+ ))
+Created: 20121130T230715
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/02089CDDC6DFE93B8EA10D9E876F983E61FEC476.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/02089CDDC6DFE93B8EA10D9E876F983E61FEC476.key
deleted file mode 100644
index 58fd0b5edbc..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/02089CDDC6DFE93B8EA10D9E876F983E61FEC476.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/052E3324B4811A197A1DE922671AA6ABE475025E.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/052E3324B4811A197A1DE922671AA6ABE475025E.key
new file mode 100644
index 00000000000..cdc19ed2660
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/052E3324B4811A197A1DE922671AA6ABE475025E.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #40AB5C863639D2154343F2196F43F95CCFAE91203324A0C63019EDA7942EA23E1F#)
+ (d #692D35D0062BE19EA22D92D7B58F8FAC5E1ACCBA78FE6260ADDDF987D2923A86#)
+ ))
+Created: 20150822T122925
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/066DBED74BA05B5AA1E2A6E4634EF6F62C0D7A5F.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/066DBED74BA05B5AA1E2A6E4634EF6F62C0D7A5F.key
new file mode 100644
index 00000000000..5a64f9f23ee
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/066DBED74BA05B5AA1E2A6E4634EF6F62C0D7A5F.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #402C67E839BFBF7BE2095CA2E9502482C8E8314936689E922B9EF870F0F3F4944F#)
+ (d #225DF7626A9308083437959FFDF825AE05919CB92670D1E22B2C6A2FB0EAE7A4#)
+ ))
+Created: 20101231T230030
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/0B0D8E451BFADF816524AF5E185EBF3DED48CA00.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/0B0D8E451BFADF816524AF5E185EBF3DED48CA00.key
new file mode 100644
index 00000000000..995b93a4fc8
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/0B0D8E451BFADF816524AF5E185EBF3DED48CA00.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #40127BA3ECD3C22145A892CC9A8EF12BBF91537B2180F54CBD22CB2696B7A7C4EA#)
+ (d #8CF76D6F3FD2893E87B08AC9A9E56419DB7D10BEC5F8AC4600516DC370E97DAB#)
+ ))
+Created: 20111231T230004
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/171B444DE92BEF997229000D9784118A94EEC1C9.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/171B444DE92BEF997229000D9784118A94EEC1C9.key
deleted file mode 100644
index 62f4ab25a69..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/171B444DE92BEF997229000D9784118A94EEC1C9.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/1967CB6C7B1C00996FCFF5930C3467D3D4FB702C.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/1967CB6C7B1C00996FCFF5930C3467D3D4FB702C.key
new file mode 100644
index 00000000000..42773a1d968
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/1967CB6C7B1C00996FCFF5930C3467D3D4FB702C.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #40D900D660C533BB480921CC5455679E9AD53C8BA2240A8946CC07759CAC14ADD5#)
+ (d #B568C991BB392303AF680093C87DF54B07288EA6D1642567D574A0FFA235B15B#)
+ ))
+Created: 20121231T230003
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/19FFEBC04DF3E037E16F6A4474DCB7984406975D.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/19FFEBC04DF3E037E16F6A4474DCB7984406975D.key
deleted file mode 100644
index 2a8ce135fb2..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/19FFEBC04DF3E037E16F6A4474DCB7984406975D.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/1E36D27DF9DAB96302D35268DADC5CE73EF45A2A.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/1E36D27DF9DAB96302D35268DADC5CE73EF45A2A.key
deleted file mode 100644
index 9f8de71c5e2..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/1E36D27DF9DAB96302D35268DADC5CE73EF45A2A.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/293109315BE584AB2EFEFCFCAD64666221D8B36C.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/293109315BE584AB2EFEFCFCAD64666221D8B36C.key
deleted file mode 100644
index 6e4a4e548fd..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/293109315BE584AB2EFEFCFCAD64666221D8B36C.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/2C9A99AF2FB073D3328B0F995BD6DE74616A6CC2.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/2C9A99AF2FB073D3328B0F995BD6DE74616A6CC2.key
new file mode 100644
index 00000000000..c4941533f4b
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/2C9A99AF2FB073D3328B0F995BD6DE74616A6CC2.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #4043E90064F42A73C20C5D3984A355F5DA2CAD5218E512B9A4038E0ACDBA237818#)
+ (d #02A2BE84BCCF0EB82D81BF991013AC77D0F8325D8FB3B98511799844DC106618#)
+ ))
+Created: 20111230T230147
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/3250B5BE67E704F82BC9AAE00EC8A0CAC8C2A94F.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/3250B5BE67E704F82BC9AAE00EC8A0CAC8C2A94F.key
new file mode 100644
index 00000000000..6fbc08d06d6
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/3250B5BE67E704F82BC9AAE00EC8A0CAC8C2A94F.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #40C5CE487C55EC9735F736D24AA11A66E05F9BBCE52EBAE5671B858585BF36E12D#)
+ (d #7DE9D5E8209B9F7E28A0C39F53FDD18125DDDEAB6D7FBD8A8D8DB2AEDE990330#)
+ ))
+Created: 20150822T113710
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/335689599E1C0F66D73ADCF51E03EE36C97D121F.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/335689599E1C0F66D73ADCF51E03EE36C97D121F.key
deleted file mode 100644
index cff58edaa89..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/335689599E1C0F66D73ADCF51E03EE36C97D121F.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/40BF94E540E3726CB150A1ADF7C1B514444B3FA6.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/40BF94E540E3726CB150A1ADF7C1B514444B3FA6.key
deleted file mode 100644
index 14af8662f79..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/40BF94E540E3726CB150A1ADF7C1B514444B3FA6.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/515D4637EFC6C09DB1F78BE8C2F2A3D63E7756C3.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/515D4637EFC6C09DB1F78BE8C2F2A3D63E7756C3.key
deleted file mode 100644
index 207a7237d3a..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/515D4637EFC6C09DB1F78BE8C2F2A3D63E7756C3.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5294CDB62DB28FBB486DE077DAF248FB32BE286A.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5294CDB62DB28FBB486DE077DAF248FB32BE286A.key
new file mode 100644
index 00000000000..76418968b70
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5294CDB62DB28FBB486DE077DAF248FB32BE286A.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #400F656F4251142032FB4C989B33F2ED84E7673BF6D2DDA34EB936839977BC1DBE#)
+ (d #12F8EC3BD83533A35D9ABE9A9100E9A41C68E4BF9247552409259F365C913D03#)
+ ))
+Created: 20150822T113710
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5A11B1935C46D0B227A73978DCA1293A85604F1D.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5A11B1935C46D0B227A73978DCA1293A85604F1D.key
deleted file mode 100644
index 85ca78da04d..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5A11B1935C46D0B227A73978DCA1293A85604F1D.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5B2B6633E89C0BD58A0FA2C785A31EAA96278695.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5B2B6633E89C0BD58A0FA2C785A31EAA96278695.key
new file mode 100644
index 00000000000..89c2fb779d7
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/5B2B6633E89C0BD58A0FA2C785A31EAA96278695.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #403C440DA39CEB741E321784F06DB254552919F71B20EF9ED031F0FA02D6D5F661#)
+ (d #4163D84B6D1B3241A23A03B1BACA8697766C8AA1A964676E7B15C84DFF9215B0#)
+ ))
+Created: 20141121T150116
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/61F5836DA69D9F63059D2665451F18E4346DF43A.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/61F5836DA69D9F63059D2665451F18E4346DF43A.key
new file mode 100644
index 00000000000..955ae5a0461
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/61F5836DA69D9F63059D2665451F18E4346DF43A.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #4006D1FF44AAE3A141CFC2018E7DDF1F97311B4939768E0F0BC7EE19150DB11D05#)
+ (d #2E1202F780E0C11F3F99176CBF786538D98465B1EC432E4D70CDFEA307012667#)
+ ))
+Created: 20141118T190135
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/62643CEBC7AEBE6817577A34399483700D76BD64.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/62643CEBC7AEBE6817577A34399483700D76BD64.key
deleted file mode 100644
index 79f3cd2b841..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/62643CEBC7AEBE6817577A34399483700D76BD64.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/64CA92780975EEB798D2083FF25AFD43A4033DB7.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/64CA92780975EEB798D2083FF25AFD43A4033DB7.key
new file mode 100644
index 00000000000..e5e07e65483
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/64CA92780975EEB798D2083FF25AFD43A4033DB7.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #4089CBD8F3505333F4366B6CEC9C77984501D01A656E3835FE5E48AC68C485448D#)
+ (d #892D99E44F5DF2DE2E78ED7B92D321422876125ED53159C80EDE105058EBA119#)
+ ))
+Created: 20111230T230130
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/6DF2D9DF7AED06F0524BEB642DF0FB48EFDBDB93.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/6DF2D9DF7AED06F0524BEB642DF0FB48EFDBDB93.key
deleted file mode 100644
index 2b464f0ccbe..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/6DF2D9DF7AED06F0524BEB642DF0FB48EFDBDB93.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/78C17E134E86E691297F7B719B2F2CDF41976234.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/78C17E134E86E691297F7B719B2F2CDF41976234.key
deleted file mode 100644
index 28a07668b21..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/78C17E134E86E691297F7B719B2F2CDF41976234.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/7A788436224049A2FE1E446E16B70DB012C830BB.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/7A788436224049A2FE1E446E16B70DB012C830BB.key
new file mode 100644
index 00000000000..4df0858b89f
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/7A788436224049A2FE1E446E16B70DB012C830BB.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #409BA575D98C4F4F414AFF624CE0E63882099BDEA95261963C9A0C1185D2D5261C#)
+ (d #62A2816B08C1489F5978E36725E3A1D844EA5CD0DD95FBD64208ABBD809DDE50#)
+ ))
+Created: 20141118T185800
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/7F714F4D9D9676638214991E96D45704E4FFC409.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/7F714F4D9D9676638214991E96D45704E4FFC409.key
deleted file mode 100644
index 137659693bd..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/7F714F4D9D9676638214991E96D45704E4FFC409.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/854752F5D8090CA36EFBDD79C72BDFF6FA2D1FF0.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/854752F5D8090CA36EFBDD79C72BDFF6FA2D1FF0.key
deleted file mode 100644
index c99824ccd43..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/854752F5D8090CA36EFBDD79C72BDFF6FA2D1FF0.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/8865328E25351B0D7697D4156A13497174F999D5.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/8865328E25351B0D7697D4156A13497174F999D5.key
new file mode 100644
index 00000000000..d1faca42080
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/8865328E25351B0D7697D4156A13497174F999D5.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #40BBF4FB0A5BD7D8C29C1FC6DF99A14930805025C9B8161535913F7B9486049C69#)
+ (d #6AB812F3623F8D8F7E20DC5072D765655EFD719DDC36A0CE38336C26D7466D40#)
+ ))
+Created: 20121130T230051
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/9504643B1FB8AAC7529134D1565DF8B4ECA01E35.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/9504643B1FB8AAC7529134D1565DF8B4ECA01E35.key
new file mode 100644
index 00000000000..711b4994cf2
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/9504643B1FB8AAC7529134D1565DF8B4ECA01E35.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #40E940D65F4BEC8205787968C2BD5B8BBAA8CF49A7ED1A2F0216E1CD595E363243#)
+ (d #5E90072772C99862227F8A8335C71DA603A3CE8E8C84F82626DD72CE6AF91950#)
+ ))
+Created: 20101231T230030
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/A3BA94EAE83509CC90DB1B77B54A51959D8DABEA.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/A3BA94EAE83509CC90DB1B77B54A51959D8DABEA.key
deleted file mode 100644
index ca128408952..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/A3BA94EAE83509CC90DB1B77B54A51959D8DABEA.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/A6BC0634D18962998AB53A0134DD2AD0DC4E0782.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/A6BC0634D18962998AB53A0134DD2AD0DC4E0782.key
new file mode 100644
index 00000000000..4d8a2da326e
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/A6BC0634D18962998AB53A0134DD2AD0DC4E0782.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #401619EB6E565EA32E569C4AB914A9631288FD0E01802835AD00362FDACC90A171#)
+ (d #71C77142D31B30081D28CD6EF9897B8808527FF1E511DF6EEF6ED23FF49C64B8#)
+ ))
+Created: 20120101T230044
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/AE6A24B17A8D0CAF9B7E000AA77F0B41D7BFFFCF.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/AE6A24B17A8D0CAF9B7E000AA77F0B41D7BFFFCF.key
deleted file mode 100644
index 06adc06c427..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/AE6A24B17A8D0CAF9B7E000AA77F0B41D7BFFFCF.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/BCFF2771AD5F49BEC185CDED47EC47D15550CB93.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/BCFF2771AD5F49BEC185CDED47EC47D15550CB93.key
new file mode 100644
index 00000000000..52e1aaa9bab
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/BCFF2771AD5F49BEC185CDED47EC47D15550CB93.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #404CD8B5371C0868C770EC91255E5703812174BED5AD019C58C0BAE9DA0383EB67#)
+ (d #6C05D0EFE8281C1D22A7E652DCCF33FF24C4DB7291D1B772FAE469D95BC4D81E#)
+ ))
+Created: 20150822T111645
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C072AF82DCCCB9A7F1B85FFA10B802DC4ED16703.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C072AF82DCCCB9A7F1B85FFA10B802DC4ED16703.key
deleted file mode 100644
index cf9a60d233b..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C072AF82DCCCB9A7F1B85FFA10B802DC4ED16703.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C36C6A8B40A2179CFE83CB0C2827358AB171CDFD.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C36C6A8B40A2179CFE83CB0C2827358AB171CDFD.key
new file mode 100644
index 00000000000..2c491e53614
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C36C6A8B40A2179CFE83CB0C2827358AB171CDFD.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #404B32D4946068A43D436843191272244F5FD661A624E2F3BAAA5B48158C14C12A#)
+ (d #6FD7F940800F8749B7709638BC020B8BA6CD7072967D9E456A39C4FCF2C09798#)
+ ))
+Created: 20111230T230130
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C43E1A079B28DFAEBB39CBA01793BDE11EF4B490.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C43E1A079B28DFAEBB39CBA01793BDE11EF4B490.key
deleted file mode 100644
index 0ed35172fe0..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/C43E1A079B28DFAEBB39CBA01793BDE11EF4B490.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CB5E00CE582C2645D2573FC16B2F14F85A7F47AA.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CB5E00CE582C2645D2573FC16B2F14F85A7F47AA.key
deleted file mode 100644
index 9061f675121..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CB5E00CE582C2645D2573FC16B2F14F85A7F47AA.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CC68630A06B048F5A91136C162C7A3273E20DE6F.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CC68630A06B048F5A91136C162C7A3273E20DE6F.key
deleted file mode 100644
index 89f6013100d..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CC68630A06B048F5A91136C162C7A3273E20DE6F.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CF723A68027A82B538F04BF4A2A1323D1B3E095C.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CF723A68027A82B538F04BF4A2A1323D1B3E095C.key
new file mode 100644
index 00000000000..5e431d38a88
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/CF723A68027A82B538F04BF4A2A1323D1B3E095C.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #40D5985FA4E3038AD26D8685213A0ADDBB87A065B228D7D2853572FE9716ABD813#)
+ (d #42441AEA366A281B481E1993A0FECA94B487AE2C13734704797131C8F3CACB68#)
+ ))
+Created: 20150822T111645
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/D6A2C195DEBA3506F0ECFBE3DDD7C57F6913DC7C.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/D6A2C195DEBA3506F0ECFBE3DDD7C57F6913DC7C.key
new file mode 100644
index 00000000000..8ed162c0236
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/D6A2C195DEBA3506F0ECFBE3DDD7C57F6913DC7C.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #40B1F1895AB187AC68A375C6604BB75F1B995BD9C36F14BAC8115F7A4E7E26F6EB#)
+ (d #7DDE136B2995E97E279A7CF8D193468742D56451D70C8EA8DEAE69BDEBFECBA2#)
+ ))
+Created: 20141118T185800
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/DB8C922A471E08FAF083EC2465AFB4063904C282.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/DB8C922A471E08FAF083EC2465AFB4063904C282.key
new file mode 100644
index 00000000000..969c2ec6906
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/DB8C922A471E08FAF083EC2465AFB4063904C282.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #40ACCC6083DE0BE9E0CD37E47B305B0AD7611AA100BD7D0BBDA489489BB0A96B10#)
+ (d #4A015D5FF823AD615F618117FD465FD515D8A6F6D1788546E46E5E2F68CA8578#)
+ ))
+Created: 20111231T230214
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/E0C3163E69C57319C6038F9EBE14F5D55DE553F7.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/E0C3163E69C57319C6038F9EBE14F5D55DE553F7.key
new file mode 100644
index 00000000000..1e4cef029f4
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/E0C3163E69C57319C6038F9EBE14F5D55DE553F7.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q
+ #40E67DD44B95A0B37286E0B7812C6AE59FD37B487323496D2FD02ADF184722EF3A#)
+ (d #55AA402F49A1896142FC1E3311C5FC734820301ADE06D1F339C8DDF0351FAC20#)
+ ))
+Created: 20141118T190135
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/E7E73903E1BF93481DE0E7C9769D6C31E1863CFF.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/E7E73903E1BF93481DE0E7C9769D6C31E1863CFF.key
deleted file mode 100644
index 41dac37574e..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/E7E73903E1BF93481DE0E7C9769D6C31E1863CFF.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/ECB164A45A1D5C5078508A9869DF6DB84DEA543B.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/ECB164A45A1D5C5078508A9869DF6DB84DEA543B.key
new file mode 100644
index 00000000000..6447ec553a8
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/ECB164A45A1D5C5078508A9869DF6DB84DEA543B.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #40964BF2C5B3BE05C4F82CCC49BA0A40B090AB03C9A4076B096115D1C61A47C470#)
+ (d #1ECC4B3E224D9A07FDA2B3B041729949B02F86F8284688D6E640D64B138FECE0#)
+ ))
+Created: 20141121T150116
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F0117468BE801ED4B81972E159A98FDD4814DCEC.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F0117468BE801ED4B81972E159A98FDD4814DCEC.key
deleted file mode 100644
index 5df7b4a5953..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F0117468BE801ED4B81972E159A98FDD4814DCEC.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F4C5EFD5779BE892CAFD5B721D68DED677C9B151.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F4C5EFD5779BE892CAFD5B721D68DED677C9B151.key
deleted file mode 100644
index 03daf80975b..00000000000
--- a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F4C5EFD5779BE892CAFD5B721D68DED677C9B151.key
+++ /dev/null
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F4E86D61A71E9CE6B0DBC65C5121846E542913B9.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F4E86D61A71E9CE6B0DBC65C5121846E542913B9.key
new file mode 100644
index 00000000000..a95f02bd3ab
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/F4E86D61A71E9CE6B0DBC65C5121846E542913B9.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #4017C963514FEF755C31DA3805DA2C4855F3E335048E3BD91038FA79B743FC1993#)
+ (d #5CDC629D6C26FD0E943792EFF739A5E633DCF506E3C587F58806D59ED346F631#)
+ ))
+Created: 20111231T230214
diff --git a/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/FE38C61A8DB32297C7C3C18E7A837D7B70263BC7.key b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/FE38C61A8DB32297C7C3C18E7A837D7B70263BC7.key
new file mode 100644
index 00000000000..ad4078fefd2
--- /dev/null
+++ b/test/lisp/gnus/mml-sec-resources/private-keys-v1.d/FE38C61A8DB32297C7C3C18E7A837D7B70263BC7.key
@@ -0,0 +1,5 @@
+Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q
+ #400D3537C332AF3DA91B8A186A8294CB663D8FABCBE26CD57255AEB3EFA4F4A49A#)
+ (d #978A174337FDA5815C221F379BDF657B90E779C9C5E085DE8160BABA695749C5#)
+ ))
+Created: 20111231T230149
diff --git a/test/lisp/gnus/mml-sec-resources/pubring.gpg b/test/lisp/gnus/mml-sec-resources/pubring.gpg
index 6bd169963df..579ca74999d 100644
--- a/test/lisp/gnus/mml-sec-resources/pubring.gpg
+++ b/test/lisp/gnus/mml-sec-resources/pubring.gpg
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/secring.gpg b/test/lisp/gnus/mml-sec-resources/secring.gpg
index b323c072c04..005f9485ae6 100644
--- a/test/lisp/gnus/mml-sec-resources/secring.gpg
+++ b/test/lisp/gnus/mml-sec-resources/secring.gpg
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-resources/trustdb.gpg b/test/lisp/gnus/mml-sec-resources/trustdb.gpg
index 09ebd8db114..132c0bb71cd 100644
--- a/test/lisp/gnus/mml-sec-resources/trustdb.gpg
+++ b/test/lisp/gnus/mml-sec-resources/trustdb.gpg
Binary files differ
diff --git a/test/lisp/gnus/mml-sec-tests.el b/test/lisp/gnus/mml-sec-tests.el
index f308a617645..e4e607b70e6 100644
--- a/test/lisp/gnus/mml-sec-tests.el
+++ b/test/lisp/gnus/mml-sec-tests.el
@@ -199,7 +199,7 @@ In both cases, the first key is customized for signing and encryption."
(let* ((mml-secure-key-preferences
'((OpenPGP (sign) (encrypt)) (CMS (sign) (encrypt))))
(pcontext (epg-make-context 'OpenPGP))
- (pkey (epg-list-keys pcontext "C3999CF1268DBEA2"))
+ (pkey (epg-list-keys pcontext "2FAF8726121EB3C6"))
(scontext (epg-make-context 'CMS))
(skey (epg-list-keys scontext "0x479DC6E2")))
(mml-secure-cust-record-keys pcontext 'encrypt "sub@example.org" pkey)
@@ -259,17 +259,17 @@ In both cases, the first key is customized for signing and encryption."
(should-not (mml-secure-check-sub-key context (car keys5) 'sign))
;; The next key has multiple subkeys.
- ;; 42466F0F is valid sign subkey, 501FFD98 is expired
- (should (mml-secure-check-sub-key context (car keys6) 'sign "42466F0F"))
+ ;; 167C1C27A9D25305 is valid sign subkey, 2DD796DBDAC43424 is expired
+ (should (mml-secure-check-sub-key context (car keys6) 'sign "167C1C27A9D25305"))
(should-not
- (mml-secure-check-sub-key context (car keys6) 'sign "501FFD98"))
- ;; DC7F66E7 is encrypt subkey
+ (mml-secure-check-sub-key context (car keys6) 'sign "2DD796DBDAC43424"))
+ ;; 8D850AA2B34936F9 is encrypt subkey
(should
- (mml-secure-check-sub-key context (car keys6) 'encrypt "DC7F66E7"))
+ (mml-secure-check-sub-key context (car keys6) 'encrypt "8D850AA2B34936F9"))
(should-not
- (mml-secure-check-sub-key context (car keys6) 'sign "DC7F66E7"))
+ (mml-secure-check-sub-key context (car keys6) 'sign "8D850AA2B34936F9"))
(should-not
- (mml-secure-check-sub-key context (car keys6) 'encrypt "42466F0F"))
+ (mml-secure-check-sub-key context (car keys6) 'encrypt "167C1C27A9D25305"))
;; The final key is just a public key.
(should (mml-secure-check-sub-key context (car keys7) 'encrypt))
@@ -305,9 +305,9 @@ In both cases, the first key is customized for signing and encryption."
;; Expired key should not be usable.
;; Will fail for Ma Gnus v0.14 and earlier.
- ;; sign@example.org has the expired subkey 0x501FFD98.
+ ;; sign@example.org has the expired subkey 0x2DD796DBDAC43424.
(should-not
- (mml-secure-find-usable-keys context "0x501FFD98" 'sign))
+ (mml-secure-find-usable-keys context "0x2DD796DBDAC43424" 'sign))
(should
(mml-secure-find-usable-keys context "no-exp@example.org" 'encrypt))
@@ -355,16 +355,16 @@ In both cases, the first key is customized for signing and encryption."
;; Search works with key IDs, with and without prefix "0x".
(should
(= 1 (length (mml-secure-find-usable-keys
- context "A142FD84" 'encrypt))))
+ context "CA9EA5175C9043FB" 'encrypt))))
(should
(= 1 (length (mml-secure-find-usable-keys
- context "0xA142FD84" 'encrypt))))
+ context "0xCA9EA5175C9043FB" 'encrypt))))
(should
(= 0 (length (mml-secure-find-usable-keys
- context "A142FD84" 'sign))))
+ context "CA9EA5175C9043FB" 'sign))))
(should
(= 0 (length (mml-secure-find-usable-keys
- context "0xA142FD84" 'sign))))
+ context "0xCA9EA5175C9043FB" 'sign))))
))))
(ert-deftest mml-secure-select-preferred-keys-1 ()
@@ -373,7 +373,7 @@ In both cases, the first key is customized for signing and encryption."
(mml-secure-test-fixture
(lambda ()
(let ((context (epg-make-context 'OpenPGP)))
- (should (equal "832F3CC6518D37BC658261B802372A42CA6D40FB"
+ (should (equal "0281C7D97E90771C0D9A61BFA049C1E9179C086B"
(mml-secure-fingerprint
(car (mml-secure-select-preferred-keys
context '("no-exp@example.org") 'encrypt)))))))))
@@ -413,18 +413,18 @@ In both cases, the first key is customized for signing and encryption."
(let ((context (epg-make-context 'OpenPGP))
(mml-secure-key-preferences
'((OpenPGP (sign) (encrypt)) (CMS (sign) (encrypt)))))
- ;; sub@example.org has two keys (268DBEA2, AE31D471).
+ ;; sub@example.org has two keys (2FAF8726121EB3C6, 8E7FEE76BB1FB195).
;; Normal preference works.
(mml-secure-cust-record-keys
- context 'encrypt "sub@example.org" (epg-list-keys context "268DBEA2"))
+ context 'encrypt "sub@example.org" (epg-list-keys context "2FAF8726121EB3C6"))
(should (mml-secure-select-preferred-keys
context '("sub@example.org") 'encrypt))
(mml-secure-cust-remove-keys context 'encrypt "sub@example.org")
- ;; Fake preference for expired (unrelated) key CE15FAE7,
+ ;; Fake preference for expired (unrelated) key 22F24E21C5010683,
;; results in error (and automatic removal of outdated preference).
(mml-secure-cust-record-keys
- context 'encrypt "sub@example.org" (epg-list-keys context "CE15FAE7"))
+ context 'encrypt "sub@example.org" (epg-list-keys context "22F24E21C5010683"))
(should-error (mml-secure-select-preferred-keys
context '("sub@example.org") 'encrypt))
(should-not
@@ -438,8 +438,8 @@ In both cases, the first key is customized for signing and encryption."
(lambda ()
(let ((pcontext (epg-make-context 'OpenPGP))
(scontext (epg-make-context 'CMS))
- (pkeys '("1E6BFA973D9E3103B77FD399C3999CF1268DBEA2"
- "14632ECAB9E227369C8DD97BF7E79AB7AE31D471"))
+ (pkeys '("4D661F67B8BC4F7F1C53C2232FAF8726121EB3C6"
+ "EB67A6310389C9AE8A5695908E7FEE76BB1FB195"))
(skeys '("0x5F88E9FC" "0x479DC6E2"))
(mml-secure-key-preferences
'((OpenPGP (sign) (encrypt)) (CMS (sign) (encrypt)))))
@@ -456,17 +456,17 @@ In both cases, the first key is customized for signing and encryption."
pcontext 'sign "sub@example.org")))
(should (= 2 (length p-e-fprs)))
(should (= 2 (length p-s-fprs)))
- (should (member "1E6BFA973D9E3103B77FD399C3999CF1268DBEA2" p-e-fprs))
- (should (member "14632ECAB9E227369C8DD97BF7E79AB7AE31D471" p-e-fprs))
- (should (member "1E6BFA973D9E3103B77FD399C3999CF1268DBEA2" p-s-fprs))
- (should (member "14632ECAB9E227369C8DD97BF7E79AB7AE31D471" p-s-fprs)))
+ (should (member "4D661F67B8BC4F7F1C53C2232FAF8726121EB3C6" p-e-fprs))
+ (should (member "EB67A6310389C9AE8A5695908E7FEE76BB1FB195" p-e-fprs))
+ (should (member "4D661F67B8BC4F7F1C53C2232FAF8726121EB3C6" p-s-fprs))
+ (should (member "EB67A6310389C9AE8A5695908E7FEE76BB1FB195" p-s-fprs)))
;; Duplicate record does not change anything.
(mml-secure-cust-record-keys
pcontext 'encrypt "sub@example.org"
- (epg-list-keys pcontext "1E6BFA973D9E3103B77FD399C3999CF1268DBEA2"))
+ (epg-list-keys pcontext "4D661F67B8BC4F7F1C53C2232FAF8726121EB3C6"))
(mml-secure-cust-record-keys
pcontext 'sign "sub@example.org"
- (epg-list-keys pcontext "1E6BFA973D9E3103B77FD399C3999CF1268DBEA2"))
+ (epg-list-keys pcontext "4D661F67B8BC4F7F1C53C2232FAF8726121EB3C6"))
(let ((p-e-fprs (mml-secure-cust-fpr-lookup
pcontext 'encrypt "sub@example.org"))
(p-s-fprs (mml-secure-cust-fpr-lookup
@@ -524,10 +524,10 @@ Pass optional INTERACTIVE to mml-secure-test-mail-fixture."
(concat "Good signature from "
(if (eq protocol 'CMS)
"0E58229B80EE33959FF718FEEF25402B479DC6E2"
- "02372A42CA6D40FB"))
+ "A049C1E9179C086B"))
gnus-info)))
(dolist (fpr signer-fprs nil)
- ;; OpenPGP: "Good signature from 02372A42CA6D40FB No Expiry <no-exp@example.org> (trust undefined) created ..."
+ ;; OpenPGP: "Good signature from A049C1E9179C086B No Expiry <no-exp@example.org> (trust undefined) created ..."
;; S/MIME: "Good signature from D06AA118653CC38E9D0CAF56ED7A2135E1582177 /CN=No Expiry (trust full) ..."
(should (string-match-p
(concat "Good signature from "
@@ -586,7 +586,7 @@ In this test, the single matching key is chosen automatically."
;; no-exp@example.org with single encryption key
(mml-secure-test-en-decrypt
method "no-exp@example.org" "sub@example.org" nil t
- (list (cons "02372A42CA6D40FB" "ED7A2135E1582177")))))
+ (list (cons "A049C1E9179C086B" "ED7A2135E1582177")))))
(ert-deftest mml-secure-en-decrypt-2 ()
"Encrypt message; then decrypt and test for expected result.
@@ -600,7 +600,7 @@ In this test, the encryption key needs to fixed among multiple ones."
(dolist (method (enc-standards) nil)
(mml-secure-test-en-decrypt
method "sub@example.org" "no-exp@example.org" nil t
- (list (cons "C3999CF1268DBEA2" "EF25402B479DC6E2")))))))
+ (list (cons "2FAF8726121EB3C6" "EF25402B479DC6E2")))))))
(ert-deftest mml-secure-en-decrypt-3 ()
"Encrypt message; then decrypt and test for expected result.
@@ -619,8 +619,8 @@ In this test, encrypt-to-self variables are set to t."
(dolist (method (enc-standards) nil)
(mml-secure-test-en-decrypt
method "sub@example.org" "no-exp@example.org" nil t
- (list (cons "C3999CF1268DBEA2" "EF25402B479DC6E2")
- (cons "02372A42CA6D40FB" "ED7A2135E1582177"))))))))
+ (list (cons "2FAF8726121EB3C6" "EF25402B479DC6E2")
+ (cons "A049C1E9179C086B" "ED7A2135E1582177"))))))))
(ert-deftest mml-secure-en-decrypt-4 ()
"Encrypt message; then decrypt and test for expected result.
@@ -628,14 +628,14 @@ In this test, encrypt-to-self variables are set to lists."
(skip-unless (test-conf))
;; Send from sub@example.org, which has two keys; encrypt to both.
(let ((mml-secure-openpgp-encrypt-to-self
- '("C3999CF1268DBEA2" "F7E79AB7AE31D471"))
+ '("2FAF8726121EB3C6" "8E7FEE76BB1FB195"))
(mml-secure-smime-encrypt-to-self
'("EF25402B479DC6E2" "4035D59B5F88E9FC")))
(dolist (method (enc-standards) nil)
(mml-secure-test-en-decrypt
method "no-exp@example.org" "sub@example.org" nil t
- (list (cons "C3999CF1268DBEA2" "EF25402B479DC6E2")
- (cons "F7E79AB7AE31D471" "4035D59B5F88E9FC"))))))
+ (list (cons "2FAF8726121EB3C6" "EF25402B479DC6E2")
+ (cons "8E7FEE76BB1FB195" "4035D59B5F88E9FC"))))))
(ert-deftest mml-secure-en-decrypt-sign-1-1-single ()
"Sign and encrypt message; then decrypt and test for expected result.
@@ -672,7 +672,7 @@ In this test, just multiple encryption and signing keys may be available."
(mml-secure-smime-sign-with-sender t))
;; Now use both keys to sign. The customized one via sign-with-sender,
;; the other one via the following setting.
- (let ((mml-secure-openpgp-signers '("F7E79AB7AE31D471"))
+ (let ((mml-secure-openpgp-signers '("8E7FEE76BB1FB195"))
(mml-secure-smime-signers '("0x5F88E9FC")))
(dolist (method (enc-sign-standards) nil)
(mml-secure-test-en-decrypt
@@ -690,7 +690,7 @@ In this test, just multiple encryption and signing keys may be available."
(let ((mml-secure-openpgp-sign-with-sender nil)
(mml-secure-smime-sign-with-sender nil)
(mml-secure-openpgp-signers
- '("F7E79AB7AE31D471" "C3999CF1268DBEA2"))
+ '("8E7FEE76BB1FB195" "2FAF8726121EB3C6"))
(mml-secure-smime-signers '("0x5F88E9FC" "0x479DC6E2")))
(dolist (method (enc-sign-standards) nil)
(mml-secure-test-en-decrypt
@@ -709,7 +709,7 @@ In this test, lists of encryption and signing keys are customized."
(scontext (epg-make-context 'CMS))
(mml-secure-openpgp-sign-with-sender t)
(mml-secure-smime-sign-with-sender t))
- (dolist (key '("F7E79AB7AE31D471" "C3999CF1268DBEA2") nil)
+ (dolist (key '("8E7FEE76BB1FB195" "2FAF8726121EB3C6") nil)
(mml-secure-cust-record-keys
pcontext 'encrypt "sub@example.org" (epg-list-keys pcontext key))
(mml-secure-cust-record-keys
@@ -745,8 +745,8 @@ Use sign-with-sender and encrypt-to-self."
(dolist (method (enc-sign-standards) nil)
(mml-secure-test-en-decrypt
method "sub@example.org" "no-exp@example.org" 1 t
- (list (cons "C3999CF1268DBEA2" "EF25402B479DC6E2")
- (cons "02372A42CA6D40FB" "ED7A2135E1582177"))))
+ (list (cons "2FAF8726121EB3C6" "EF25402B479DC6E2")
+ (cons "A049C1E9179C086B" "ED7A2135E1582177"))))
))))
(ert-deftest mml-secure-sign-verify-1 ()
@@ -765,7 +765,7 @@ Use sign-with-sender and encrypt-to-self."
;; From sub@example.org, sign with two keys;
;; sign-with-sender and one from signers-variable:
- (let ((mml-secure-openpgp-signers '("02372A42CA6D40FB"))
+ (let ((mml-secure-openpgp-signers '("A049C1E9179C086B"))
(mml-secure-smime-signers
'("D06AA118653CC38E9D0CAF56ED7A2135E1582177")))
(mml-secure-test-en-decrypt
@@ -781,7 +781,7 @@ With Ma Gnus v0.14 and earlier a signature would be created with a wrong key."
(lambda ()
(let ((with-smime nil)
(mml-secure-openpgp-sign-with-sender nil)
- (mml-secure-openpgp-signers '("501FFD98")))
+ (mml-secure-openpgp-signers '("2DD796DBDAC43424")))
(dolist (method (sign-standards) nil)
(mml-secure-test-en-decrypt
method "no-exp@example.org" "sign@example.org" 1 nil)
diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el
index 6f1dcfa5b6b..0fcaacb6443 100644
--- a/test/lisp/help-tests.el
+++ b/test/lisp/help-tests.el
@@ -181,8 +181,12 @@ M-g M-c switch-to-completions
(ert-deftest help-tests-substitute-command-keys/keymap-change ()
(with-substitute-command-keys-test
+ ;; Global binding should be found even if specifying a specific map
(test "\\<minibuffer-local-must-match-map>\\[abort-recursive-edit]" "C-]")
- (test "\\<emacs-lisp-mode-map>\\[eval-defun]" "C-M-x")))
+ (test "\\<emacs-lisp-mode-map>\\[eval-defun]" "C-M-x")
+ ;; Specific map overrides advertised-binding
+ (test "\\<undo-repeat-map>\\[undo]" "u")
+ (test "\\[undo]" "C-x u")))
(defvar-keymap help-tests-remap-map
:full t
diff --git a/test/lisp/image/image-dired-util-tests.el b/test/lisp/image/image-dired-util-tests.el
new file mode 100644
index 00000000000..63d42f56dea
--- /dev/null
+++ b/test/lisp/image/image-dired-util-tests.el
@@ -0,0 +1,71 @@
+;;; image-dired-util-tests.el --- Tests for image-dired.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'image-dired)
+(require 'image-dired-util)
+(require 'xdg)
+
+(ert-deftest image-dired-thumb-name/standard ()
+ (let ((image-dired-thumbnail-storage 'standard))
+ (should (file-name-absolute-p (image-dired-thumb-name "foo.jpg")))
+ (should (file-name-absolute-p (image-dired-thumb-name "/tmp/foo.jpg")))
+ (should (equal
+ (file-name-directory (image-dired-thumb-name "foo.jpg"))
+ (file-name-directory (image-dired-thumb-name "/tmp/foo.jpg"))))
+ (should (string-search (xdg-cache-home)
+ (image-dired-thumb-name "foo.jpg")))
+ (should (string-match (rx (in "0-9a-f") ".png")
+ (image-dired-thumb-name "foo.jpg")))))
+
+(ert-deftest image-dired-thumb-name/image-dired ()
+ ;; Avoid trying to create `image-dired-dir'.
+ (ert-with-temp-directory dir
+ (let ((image-dired-dir dir)
+ (image-dired-thumbnail-storage 'image-dired))
+ (should (file-name-absolute-p (image-dired-thumb-name "foo.jpg")))
+ (should (file-name-absolute-p (image-dired-thumb-name "/tmp/foo.jpg")))
+ (should (equal
+ (file-name-directory (image-dired-thumb-name "foo.jpg"))
+ (file-name-directory (image-dired-thumb-name "/tmp/foo.jpg"))))
+ (should (equal (file-name-nondirectory
+ ;; The checksum is based on the file name.
+ (image-dired-thumb-name "/some/path/foo.jpg"))
+ "dc4e6f7068157023e7f2e8362d15bdd2e3ca89e4.jpg"))
+ (should (equal (file-name-extension
+ (image-dired-thumb-name "foo.gif"))
+ "jpg")))))
+
+(ert-deftest image-dired-thumb-name/per-directory ()
+ (let ((image-dired-thumbnail-storage 'per-directory))
+ (should (file-name-absolute-p (image-dired-thumb-name "foo.jpg")))
+ (should (file-name-absolute-p (image-dired-thumb-name "/tmp/foo.jpg")))
+ (should (equal
+ (file-name-nondirectory (image-dired-thumb-name "foo.jpg"))
+ (file-name-nondirectory (image-dired-thumb-name "/tmp/foo.jpg"))))
+ (should (equal (file-name-split (image-dired-thumb-name "/tmp/foo.jpg"))
+ '("" "tmp" ".image-dired" "foo.jpg.thumb.jpg")))
+ (should (equal (file-name-nondirectory
+ (image-dired-thumb-name "foo.jpg"))
+ "foo.jpg.thumb.jpg"))))
+
+;;; image-dired-util-tests.el ends here
diff --git a/test/lisp/image/wallpaper-tests.el b/test/lisp/image/wallpaper-tests.el
new file mode 100644
index 00000000000..cb6818f8c1b
--- /dev/null
+++ b/test/lisp/image/wallpaper-tests.el
@@ -0,0 +1,181 @@
+;;; wallpaper-tests.el --- tests for wallpaper.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'wallpaper)
+
+(ert-deftest wallpaper--find-setter ()
+ (skip-unless (executable-find "touch"))
+ (let (wallpaper--current-setter
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" "/tmp/touched"))))
+ (should (wallpaper--find-setter))))
+
+(ert-deftest wallpaper--find-setter/call-predicate ()
+ (skip-unless (executable-find "touch"))
+ (let* ( wallpaper--current-setter called
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" "/tmp/touched"
+ :predicate (lambda () (setq called t))))))
+ (should-not called)
+ (wallpaper--find-setter)
+ (should called)))
+
+(ert-deftest wallpaper--find-setter/set-current-setter ()
+ (skip-unless (executable-find "touch"))
+ (let (wallpaper--current-setter
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" "/tmp/touched"))))
+ (wallpaper--find-setter)
+ (should wallpaper--current-setter)))
+
+(ert-deftest wallpaper-set/runs-command ()
+ (skip-unless (executable-find "touch"))
+ (ert-with-temp-file fil-jpg
+ :suffix ".jpg"
+ (ert-with-temp-file fil
+ (let* ( wallpaper--current-setter
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" fil)))
+ (wallpaper-command (wallpaper--find-command))
+ (wallpaper-command-args (wallpaper--find-command-args)))
+ (delete-file fil)
+ (let ((process (wallpaper-set fil-jpg)))
+ (while (process-live-p process)
+ (sit-for 0.001))
+ ;; Touch has recreated the file:
+ (should (file-exists-p fil)))))))
+
+(ert-deftest wallpaper-set/runs-command/detach ()
+ (skip-unless (executable-find "touch"))
+ (ert-with-temp-file fil-jpg
+ :suffix ".jpg"
+ (ert-with-temp-file fil
+ (let* ( wallpaper--current-setter
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" fil
+ :detach t)))
+ (wallpaper-command (wallpaper--find-command))
+ (wallpaper-command-args (wallpaper--find-command-args)))
+ (delete-file fil)
+ (wallpaper-set fil-jpg)
+ (while (not (file-exists-p fil))
+ (sit-for 0.001))
+ ;; Touch has recreated the file:
+ (should (file-exists-p fil))))))
+
+(ert-deftest wallpaper-set/calls-init-action ()
+ (skip-unless (executable-find "touch"))
+ (ert-with-temp-file fil-jpg
+ :suffix ".jpg"
+ (ert-with-temp-file fil
+ (let* ( wallpaper--current-setter called
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" fil
+ :init-action (lambda () (setq called t)))))
+ (wallpaper-command (wallpaper--find-command))
+ (wallpaper-command-args (wallpaper--find-command-args)))
+ (should (functionp (wallpaper-setter-init-action wallpaper--current-setter)))
+ (wallpaper-set fil-jpg)
+ (should called)))))
+
+(ert-deftest wallpaper-set/calls-wallpaper-set-function ()
+ (skip-unless (executable-find "touch"))
+ (ert-with-temp-file fil-jpg
+ :suffix ".jpg"
+ (let* ( wallpaper--current-setter called
+ (wallpaper--default-setters
+ (wallpaper--default-methods-create
+ ("touch" "touch" "foo")))
+ (wallpaper-set-function
+ (lambda (file) (setq called file))))
+ (wallpaper--find-setter)
+ (wallpaper-set fil-jpg)
+ (should (equal called fil-jpg)))))
+
+(ert-deftest wallpaper--find-command/return-string ()
+ (should (or (not (wallpaper--find-command))
+ (stringp (wallpaper--find-command)))))
+
+(ert-deftest wallpaper--find-command-args/return-list ()
+ (should (or (not (wallpaper--find-command-args))
+ (listp (wallpaper--find-command-args)))))
+
+(ert-deftest wallpaper--image-file-regexp/return-string ()
+ (should (stringp (wallpaper--image-file-regexp))))
+
+(ert-deftest wallpaper--get-default-file/empty-gives-nil ()
+ (with-temp-buffer
+ (should-not (wallpaper--get-default-file))))
+
+(ert-deftest wallpaper--get-default-file/visiting-file ()
+ (ert-with-temp-file _
+ :buffer buf
+ :suffix (format ".%s" (car image-file-name-extensions))
+ (with-current-buffer buf
+ (should (wallpaper--get-default-file)))))
+
+(ert-deftest wallpaper--get-default-file/file-at-point ()
+ ;; ffap needs the file to exist
+ (ert-with-temp-file fil
+ :buffer buf
+ :suffix (format ".%s" (car image-file-name-extensions))
+ (with-current-buffer buf
+ (insert fil)
+ (should (stringp (wallpaper--get-default-file))))))
+
+(ert-deftest wallpaper--format-arg/filename ()
+ (should (file-name-absolute-p (wallpaper--format-arg "%f" "foo.jpg"))))
+
+(ert-deftest wallpaper--format-arg/filename-hex ()
+ (should (equal (wallpaper--format-arg "%F" "foo bar åäö.jpg")
+ "foo%20bar%20%C3%A5%C3%A4%C3%B6.jpg")))
+
+(ert-deftest wallpaper--format-arg/width ()
+ (skip-unless noninteractive)
+ (should (equal (wallpaper--format-arg "%w" "foo.jpg")
+ (number-to-string wallpaper-default-width))))
+
+(ert-deftest wallpaper--format-arg/height ()
+ (skip-unless noninteractive)
+ (should (equal (wallpaper--format-arg "%h" "foo.jpg")
+ (number-to-string wallpaper-default-height))))
+
+(ert-deftest wallpaper--format-arg/screen ()
+ (skip-unless noninteractive)
+ (should (equal (wallpaper--format-arg "%S" "foo.jpg") "0")))
+
+(ert-deftest wallpaper--format-arg/monitor ()
+ (skip-unless noninteractive)
+ (should (equal (wallpaper--format-arg "%M" "foo.jpg") "0")))
+
+(ert-deftest wallpaper--format-arg/workspace ()
+ (skip-unless noninteractive)
+ (should (equal (wallpaper--format-arg "%W" "foo.jpg") "0")))
+
+;;; wallpaper-tests.el ends here
diff --git a/test/lisp/international/ucs-normalize-tests.el b/test/lisp/international/ucs-normalize-tests.el
index 774a3ea7ec9..9e359d5022f 100644
--- a/test/lisp/international/ucs-normalize-tests.el
+++ b/test/lisp/international/ucs-normalize-tests.el
@@ -207,8 +207,17 @@ must be true for all conformant implementations:
16326 16327 16328 16329 16330 16331 16332 16333
16334 16335 16336 16337 16338 16339 16340 16341
16342 16343 16344 16345 16346 16347 16348 16349
- 16350 16351 16488 16489 16490 16491 16492 16493
- 16494 16495 16496 16497))
+ 16350 16351 16352 16353 16354 16355 16356 16357
+ 16358 16359 16360 16361 16362 16363 16364 16365
+ 16366 16367 16368 16369 16370 16371 16372 16373
+ 16374 16375 16376 16377 16378 16379 16380 16381
+ 16382 16383 16384 16385 16386 16387 16388 16389
+ 16390 16391 16392 16393 16394 16395 16396 16397
+ 16398 16399 16400 16401 16402 16403 16404 16405
+ 16406 16407 16408 16409 16410 16411 16412 16413
+ 16550 16551 16552 16553 16554 16555 16556 16557
+ 16488 16489 16490 16491 16492 16493 16494 16495
+ 16496 16497 16558 16559))
;; Keep a record of failures, for consulting afterwards (the ert
;; backtrace only shows a truncated version of these lists).
@@ -293,17 +302,19 @@ must be true for all conformant implementations:
17692 17693 17694 17707 17708 17713 17714 17715
17716 17727 17728 17733 17734 17739 17740 17745
17746 17749 17750 17753 17754 17759 17760 17767
- 17768 17807 17808 17809 17810 17811 17812 17813
- 17814 17816 17843 17844 17845 17846 17851 17852
- 17861 17875 17876 17879 17880 17899 17900 17911
- 17912 17913 17914 17915 17916 17917 17918 17919
- 17920 17921 17922 17927 17928 17929 17930 17931
- 17932 17933 17935 17937 17938 17939 17940 17941
- 17943 17945 17947 17949 17951 17952 17953 17955
- 17957 17959 17961 17962 17967 17968 17987 17988
- 17993 17994 18003 18004 18005 18006 18007 18008
- 18009 18010 18011 18012 18017 18018 18019 18020
- 18021 18022 18023 18024 18041 18042 18053 18054
+ 17768 17789 17790 17801 17802 17807 17808 17809
+ 17810 17811 17812 17813 17814 17815 17816 17821
+ 17822 17829 17830 17843 17844 17845 17846 17851
+ 17852 17861 17875 17876 17879 17880 17899 17900
+ 17097 17907 17908 17911 17912 17913 17914 17915
+ 17916 17917 17918 17919 17920 17921 17922 17927
+ 17928 17929 17930 17931 17932 17933 17935 17937
+ 17938 17939 17940 17941 17943 17945 17947 17949
+ 17951 17952 17953 17955 17957 17959 17961 17962
+ 17967 17968 17987 17988 17993 17994 18003 18004
+ 18005 18006 18007 18008 18009 18010 18011 18012
+ 18017 18018 18019 18020 18021 18022 18023 18024
+ 18041 18042 18049 18050 18053 18054 18055 18056
18069 18070 18079 18080 18163 18164 18165 18166
18171 18172 18175 18176 18211 18212 18219 18220
18221 18222 18223 18224 18225 18226 18301 18302
@@ -316,27 +327,37 @@ must be true for all conformant implementations:
18521 18523 18524 18525 18527 18528 18531 18537
18538 18539 18541 18543 18545 18547 18549 18550
18551 18553 18554 18555 18557 18558 18559 18560
- 18561 18563 18564 18565 18566 18567 18569 18571
- 18573 18575 18577 18579 18581 18583 18585 18587
- 18589 18591 18593 18595 18596 18597 18599 18601
- 18602 18603 18605 18606 18607 18609 18611 18612
- 18613 18615 18617 18618 18619 18621 18623 18624
- 18625 18627 18629 18631 18633 18635 18636 18637
- 18639 18641 18643 18645 18647 18649 18651 18653
- 18655 18657 18659 18661 18663 18665 18667 18668
- 18669 18670 18671 18674 18676 18686 18688 18690
- 18692 18694 18695 18696 18697 18698 18699 18700
- 18701 18702 18703 18704 18705 18706 18707 18708
- 18709 18710 18721 18722 18723 18724 18739 18741
- 18743 18745 18747 18749 18751 18753 18755 18757
- 18759 18761 18763 18765 18767 18769 18771 18773
- 18775 18777 18779 18781 18783 18785 18787 18789
- 18791 18793 18795 18797 18799 18801 18803 18805
- 18807 18809 18811 18813 18815 18817 18819 18821
- 18823 18825 18827 18829 18831 18833 18835 18837
- 18839 18840 18841 18842 18843 18844 18845 18846
- 18847 18848 18849 18850 18851 18852 18853 18855
- 18857 18859 18861 18863 18865 18866))
+ 18561 18562 18563 18564 18565 18566 18567 18569
+ 18571 18573 18575 18577 18579 18581 18583 18585
+ 18587 18589 18591 18593 18595 18596 18597 18599
+ 18601 18602 18603 18605 18606 18607 18609 18611
+ 18612 18613 18615 18617 18618 18619 18621 18622
+ 18623 18624 18625 18626 18627 18628 18629 18631
+ 18632 18633 18634 18635 18636 18637 18639 18641
+ 18643 18645 18647 18649 18651 18653 18655 18657
+ 18659 18661 18663 18664 18665 18667 18668 18669
+ 18670 18671 18673 18674 18675 18676 18677 18679
+ 18680 18681 18683 18685 18686 18687 18688 18689
+ 18690 18691 18692 18693 18694 18695 18696 18697
+ 18698 18699 18700 18701 18702 18703 18704 18705
+ 18706 18707 18708 18709 18710 18711 18712 18713
+ 18714 18715 18717 18719 18721 18722 18723 18724
+ 18725 18727 18729 18731 18733 18735 18737 18739
+ 18740 18741 18742 18743 18745 18747 18749 18751
+ 18753 18755 18757 18759 18761 18763 18765 18767
+ 18769 18771 18773 18775 18777 18779 18781 18783
+ 18785 18787 18789 18791 18793 18795 18797 18799
+ 18801 18803 18805 18807 18809 18811 18813 18815
+ 18817 18819 18821 18823 18825 18827 18829 18831
+ 18833 18835 18837 18839 18840 18841 18842 18843
+ 18844 18845 18846 18847 18848 18849 18850 18851
+ 18852 18853 18855 18857 18859 18861 18863 18865
+ 18866 18867 18869 18871 18873 18875 18877 18879
+ 18881 18883 18885 18887 18888 18889 18891 18893
+ 18895 18897 18899 18901 18903 18905 18907 18909
+ 18911 18913 18914 18915 18916 18917 18918 18919
+ 18920 18921 18923 18925 18927 18929 18931 18933
+ 18935 18937 18939 18941 18943 18945 18947 18948))
(ert-deftest ucs-normalize-part2 ()
:tags '(:expensive-test)
diff --git a/test/lisp/net/mailcap-tests.el b/test/lisp/net/mailcap-tests.el
index c4f011dd1a7..9e60a243b3d 100644
--- a/test/lisp/net/mailcap-tests.el
+++ b/test/lisp/net/mailcap-tests.el
@@ -239,7 +239,7 @@
(print . "print1")))))))))
(ert-deftest mailcap-add-mailcap-entry-new-minor-to-various-major-positions ()
- "Add a new minor entry to major entries at various postions
+ "Add a new minor entry to major entries at various positions
in ‘mailcap-mime-data’."
(let ((mailcap-mime-data
(list
@@ -515,7 +515,7 @@ in ‘mailcap-mime-data’."
In its current implementation ‘mailcap-add-mailcap-entry’ loses
extra fields of an entry already existing in ‘mailcap-mime-data’.
This test does not actually verify a correct result; it merely
-checks whether ‘mailcap-add-mailcap-entry’ behaviour is still the
+checks whether ‘mailcap-add-mailcap-entry’ behavior is still the
incorrect one. As such, it can be satisfied by any other result
than the expected and known wrong one, and its success does not
help to verify the correct addition and merging of an entry."
diff --git a/test/lisp/net/puny-resources/IdnaTestV2.txt b/test/lisp/net/puny-resources/IdnaTestV2.txt
index ed2f32e129f..4b8d5984a7c 100644
--- a/test/lisp/net/puny-resources/IdnaTestV2.txt
+++ b/test/lisp/net/puny-resources/IdnaTestV2.txt
@@ -2,12 +2,12 @@
# Date: 2021-08-17, 19:34:01 GMT
# © 2021 Unicode®, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode IDNA Compatible Preprocessing for UTS #46
# Version: 14.0.0
#
-# For documentation and usage, see http://www.unicode.org/reports/tr46
+# For documentation and usage, see https://www.unicode.org/reports/tr46
#
# Test cases for verifying UTS #46 conformance.
#
diff --git a/test/lisp/thumbs-tests.el b/test/lisp/obsolete/thumbs-tests.el
index a8972394fa5..a8972394fa5 100644
--- a/test/lisp/thumbs-tests.el
+++ b/test/lisp/obsolete/thumbs-tests.el
diff --git a/test/lisp/pcomplete-tests.el b/test/lisp/pcomplete-tests.el
new file mode 100644
index 00000000000..00a82502f30
--- /dev/null
+++ b/test/lisp/pcomplete-tests.el
@@ -0,0 +1,100 @@
+;;; pcomplete-tests.el --- Tests for pcomplete.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'pcomplete)
+
+(ert-deftest pcomplete-test-parse-gpg-help ()
+ (cl-letf ((pcomplete-from-help (make-hash-table :test #'equal))
+ ((symbol-function 'call-process)
+ (lambda (&rest _) (insert "\
+gpg (GnuPG) 2.3.7
+
+Commands:
+
+ -s, --sign make a signature
+ --clear-sign make a clear text signature
+ -b, --detach-sign make a detached signature
+ --tofu-policy VALUE set the TOFU policy for a key
+
+Options to specify keys:
+ -r, --recipient USER-ID encrypt for USER-ID
+ -u, --local-user USER-ID use USER-ID to sign or decrypt
+
+(See the man page for a complete listing of all commands and options)
+
+Examples:
+
+ -se -r Bob [file] sign and encrypt for user Bob
+ --clear-sign [file] make a clear text signature
+"))))
+ (should
+ (equal-including-properties
+ (pcomplete-from-help "gpg --help" :narrow-end "^ -se")
+ '(#("-s" 0 1 (pcomplete-help "make a signature"))
+ #("--sign" 0 1 (pcomplete-help "make a signature"))
+ #("--clear-sign" 0 1 (pcomplete-help "make a clear text signature"))
+ #("-b" 0 1 (pcomplete-help "make a detached signature"))
+ #("--detach-sign" 0 1 (pcomplete-help "make a detached signature"))
+ #("--tofu-policy" 0 1
+ (pcomplete-help "set the TOFU policy for a key" pcomplete-annotation " VALUE"))
+ #("-r" 0 1 (pcomplete-help "encrypt for USER-ID"))
+ #("--recipient" 0 1
+ (pcomplete-help "encrypt for USER-ID" pcomplete-annotation " USER-ID"))
+ #("-u" 0 1
+ (pcomplete-help "use USER-ID to sign or decrypt"))
+ #("--local-user" 0 1
+ (pcomplete-help "use USER-ID to sign or decrypt" pcomplete-annotation " USER-ID")))))))
+
+(ert-deftest pcomplete-test-parse-git-help ()
+ (cl-letf ((pcomplete-from-help (make-hash-table :test #'equal))
+ ((symbol-function 'call-process)
+ (lambda (&rest _) (insert "\
+usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
+ [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
+ [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
+ [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
+ [--super-prefix=<path>] [--config-env=<name>=<envvar>]
+ <command> [<args>]
+"))))
+ (should
+ (equal-including-properties
+ (pcomplete-from-help "git help"
+ :margin "\\(\\[\\)-"
+ :separator " | "
+ :description "\\`")
+ '("-v" "--version" "-h" "--help"
+ #("-C" 0 1 (pcomplete-annotation " <path>"))
+ #("-c" 0 1 (pcomplete-annotation " <name>"))
+ #("--exec-path" 0 1 (pcomplete-annotation "[=<path>]"))
+ "--html-path" "--man-path" "--info-path"
+ "-p" "--paginate" "-P" "--no-pager"
+ "--no-replace-objects" "--bare"
+ #("--git-dir=" 0 1 (pcomplete-annotation "<path>"))
+ #("--work-tree=" 0 1 (pcomplete-annotation "<path>"))
+ #("--namespace=" 0 1 (pcomplete-annotation "<name>"))
+ #("--super-prefix=" 0 1 (pcomplete-annotation "<path>"))
+ #("--config-env=" 0 1 (pcomplete-annotation "<name>")))))))
+
+(provide 'pcomplete-tests)
+;;; pcomplete-tests.el ends here
diff --git a/test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl b/test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl
new file mode 100644
index 00000000000..566b7e7550f
--- /dev/null
+++ b/test/lisp/progmodes/cperl-mode-resources/cperl-bug-11996.pl
@@ -0,0 +1,8 @@
+{
+ my @zzzz=(\%seen_couchrequsts, \%seen_people );
+ my @zzzz=\(%seen_couchrequsts, %seen_people );
+ my @zzzz=(\%seen_couchrequsts, \%seen_people );
+}
+
+print "\"Watch out\"";
+$ref = \"howdy";
diff --git a/test/lisp/progmodes/cperl-mode-resources/cperl-indents.erts b/test/lisp/progmodes/cperl-mode-resources/cperl-indents.erts
new file mode 100644
index 00000000000..6b874ffaa1f
--- /dev/null
+++ b/test/lisp/progmodes/cperl-mode-resources/cperl-indents.erts
@@ -0,0 +1,26 @@
+Code:
+ (lambda ()
+ (cperl-mode)
+ (indent-region (point-min) (point-max)))
+
+Name: cperl-indent1
+
+=-=
+{
+ print "",
+ "",
+ foo::bar(),
+ "";
+}
+=-=-=
+
+Name: cperl-indents1
+
+=-=
+{
+ print "",
+ "",
+ foobar(),
+ "";
+}
+=-=-=
diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el
index 7eb2d9be756..1bb206e7040 100644
--- a/test/lisp/progmodes/cperl-mode-tests.el
+++ b/test/lisp/progmodes/cperl-mode-tests.el
@@ -723,6 +723,18 @@ created by CPerl mode, so skip it for Perl mode."
;;; Tests for issues reported in the Bug Tracker
+(ert-deftest cperl-test-bug-997 ()
+ "Test that we distinguish a regexp match when there's nothing before it."
+ (let ((code "# some comment\n\n/fontify me/;\n"))
+ (with-temp-buffer
+ (funcall cperl-test-mode)
+ (insert code)
+ (font-lock-ensure)
+ (goto-char (point-min))
+ (search-forward "/f")
+ (should (equal (get-text-property (point) 'face)
+ 'font-lock-string-face)))))
+
(defun cperl-test--run-bug-10483 ()
"Runs a short program, intended to be under timer scrutiny.
This function is intended to be used by an Emacs subprocess in
@@ -776,6 +788,36 @@ under timeout control."
(should (string-match
"poop ('foo', \n 'bar')" (buffer-string))))))
+(ert-deftest cperl-test-bug-11996 ()
+ "Verify that we give the right syntax property to a backslash operator."
+ (with-temp-buffer
+ (insert-file-contents (ert-resource-file "cperl-bug-11996.pl"))
+ (funcall cperl-test-mode)
+ (font-lock-ensure)
+ (goto-char (point-min))
+ (re-search-forward "\\(\\\\(\\)")
+ (save-excursion
+ (goto-char (match-beginning 1))
+ (should (equal (syntax-after (point)) (string-to-syntax ".")))
+ ;; `forward-sexp' shouldn't complain.
+ (forward-sexp)
+ (should (char-equal (char-after) ?\;)))
+ (re-search-forward "\\(\\\\\"\\)")
+ (save-excursion
+ (goto-char (match-beginning 1))
+ (should (equal (syntax-after (point)) (string-to-syntax "\\")))
+ (should (equal (get-text-property (point) 'face) 'font-lock-string-face)))
+ (re-search-forward "\\(\\\\\"\\)")
+ (save-excursion
+ (goto-char (match-beginning 1))
+ (should (equal (syntax-after (point)) (string-to-syntax "\\"))))
+ (re-search-forward "\\(\\\\\"\\)")
+ (save-excursion
+ (goto-char (match-beginning 1))
+ (should (equal (syntax-after (point)) (string-to-syntax ".")))
+ (should (equal (get-text-property (1+ (point)) 'face)
+ 'font-lock-string-face)))))
+
(ert-deftest cperl-test-bug-14343 ()
"Verify that inserting text into a HERE-doc string with Elisp
does not break fontification."
@@ -1103,4 +1145,7 @@ as a regex."
(funcall cperl-test-mode)
(should-not (nth 3 (syntax-ppss 3)))))
+(ert-deftest test-indentation ()
+ (ert-test-erts-file (ert-resource-file "cperl-indents.erts")))
+
;;; cperl-mode-tests.el ends here
diff --git a/test/lisp/progmodes/hideshow-tests.el b/test/lisp/progmodes/hideshow-tests.el
index ee2a0c7c4c1..22d73fb3c46 100644
--- a/test/lisp/progmodes/hideshow-tests.el
+++ b/test/lisp/progmodes/hideshow-tests.el
@@ -41,6 +41,18 @@ always located at the beginning of buffer."
(goto-char (point-min))
,@body))
+(defmacro hideshow-tests-with-temp-buffer-selected (mode contents &rest body)
+ "Create and switch to a `hs-minor-mode' enabled MODE temp buffer with CONTENTS.
+BODY is code to be executed within the temp buffer. Point is
+always located at the beginning of buffer."
+ (declare (indent 1) (debug t))
+ `(ert-with-test-buffer-selected ()
+ (,mode)
+ (hs-minor-mode 1)
+ (insert ,contents)
+ (goto-char (point-min))
+ ,@body))
+
(defun hideshow-tests-look-at (string &optional num restore-point)
"Move point at beginning of STRING in the current buffer.
Optional argument NUM defaults to 1 and is an integer indicating
@@ -96,6 +108,39 @@ default to `point-min' and `point-max' respectively."
(overlay-end overlay))))
(buffer-substring-no-properties (point-min) (point-max)))))
+(defun hideshow-tests-make-event-at (string)
+ "Make dummy mouse event at beginning of STRING."
+ (save-excursion
+ (let ((pos (hideshow-tests-look-at string)))
+ (vector
+ `(S-mouse-2
+ (,(get-buffer-window) ,pos (1 . 1) 0 nil ,pos (1 . 1)
+ nil (1 . 1) (1 . 1)))))))
+
+(ert-deftest hideshow-already-hidden-p-1 ()
+ (let ((contents "
+int
+main()
+{
+ printf(\"Hello\\n\");
+}
+"))
+ (hideshow-tests-with-temp-buffer
+ c-mode
+ contents
+ (hideshow-tests-look-at "printf")
+ (should (not (hs-already-hidden-p)))
+ (hs-hide-block)
+ (goto-char (point-min))
+ (hideshow-tests-look-at "{")
+ (should (hs-already-hidden-p))
+ (forward-line -1)
+ (should (not (hs-already-hidden-p)))
+ (hideshow-tests-look-at "}")
+ (should (hs-already-hidden-p))
+ (forward-line)
+ (should (not (hs-already-hidden-p))))))
+
(ert-deftest hideshow-hide-block-1 ()
"Should hide current block."
(let ((contents "
@@ -263,6 +308,67 @@ main(int argc, char **argv)
}
"))))
+(ert-deftest hideshow-toggle-hiding-1 ()
+ "Should toggle hiding/showing of a block."
+ (let ((contents "
+int
+main()
+{
+ printf(\"Hello\\n\");
+}
+"))
+ (hideshow-tests-with-temp-buffer
+ c-mode
+ contents
+ (hideshow-tests-look-at "printf")
+ (hs-toggle-hiding)
+ (should (string=
+ (hideshow-tests-visible-string)
+ "
+int
+main()
+{}
+"))
+ (hs-toggle-hiding)
+ (should (string= (hideshow-tests-visible-string) contents)))))
+
+(ert-deftest hideshow-mouse-toggle-hiding-1 ()
+ "Should toggle hiding/showing of a block by mouse events."
+ (let ((contents "
+int
+main()
+{
+ printf(\"Hello\\n\");
+}
+")
+ (hidden "
+int
+main()
+{}
+")
+ (call-at (lambda (str)
+ (let* ((events (hideshow-tests-make-event-at str))
+ (last-nonmenu-event (aref events 0)))
+ (call-interactively #'hs-toggle-hiding nil events)))))
+ (hideshow-tests-with-temp-buffer-selected
+ c-mode
+ contents
+ ;; Should not hide the block when clicked outside of the block.
+ (funcall call-at "int")
+ (should (string= (hideshow-tests-visible-string) contents))
+ ;; Should hide the block when clicked inside of the block.
+ (goto-char (point-min))
+ (funcall call-at "printf")
+ (should (string= (hideshow-tests-visible-string) hidden))
+ ;; Should not show the block when clicked outside of the block.
+ (goto-char (point-min))
+ (funcall call-at "int")
+ (should (string= (hideshow-tests-visible-string) hidden))
+ ;; Should show the block when clicked inside of the block.
+ (goto-char (point-min))
+ (funcall call-at "}")
+ (should (string= (hideshow-tests-visible-string) contents)))))
+
(provide 'hideshow-tests)
;;; hideshow-tests.el ends here
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 20a7a0132a8..9ad2d169308 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -43,6 +43,37 @@ always located at the beginning of buffer."
(goto-char (point-min))
,@body)))
+(defun python-tests-shell-wait-for-prompt ()
+ "Wait for the prompt in the shell buffer."
+ (python-shell-with-shell-buffer
+ (while (not (if-let ((prompt (python-util-comint-last-prompt)))
+ (python-shell-comint-end-of-output-p
+ (buffer-substring-no-properties
+ (car prompt) (cdr prompt)))))
+ (sit-for 0.1))))
+
+(defmacro python-tests-with-temp-buffer-with-shell (contents &rest body)
+ "Create a `python-mode' enabled temp buffer with CONTENTS and `run-python'.
+BODY is code to be executed within the temp buffer. Point is
+always located at the beginning of buffer. Native completion is
+turned off. Shell buffer will be killed on exit."
+ (declare (indent 1) (debug t))
+ `(with-temp-buffer
+ (let ((python-indent-guess-indent-offset nil)
+ (python-shell-completion-native-enable nil))
+ (python-mode)
+ (unwind-protect
+ (progn
+ (run-python nil t)
+ (insert ,contents)
+ (goto-char (point-min))
+ (python-tests-shell-wait-for-prompt)
+ ,@body)
+ (when (python-shell-get-buffer)
+ (python-shell-with-shell-buffer
+ (let (kill-buffer-hook kill-buffer-query-functions)
+ (kill-buffer))))))))
+
(defmacro python-tests-with-temp-file (contents &rest body)
"Create a `python-mode' enabled file with CONTENTS.
BODY is code to be executed within the temp buffer. Point is
@@ -2342,6 +2373,21 @@ class C:
(beginning-of-line)
(point))))))
+(ert-deftest python-nav-beginning-of-defun-6 ()
+ (python-tests-with-temp-buffer
+ "
+class C:
+ def foo(self):
+ pass
+"
+ (python-tests-look-at "self")
+ (should (= (save-excursion
+ (python-nav-beginning-of-defun)
+ (point))
+ (save-excursion
+ (beginning-of-line)
+ (point))))))
+
(ert-deftest python-nav-end-of-defun-1 ()
(python-tests-with-temp-buffer
"
@@ -2472,6 +2518,26 @@ def \\
(save-excursion
(point-max))))))
+(ert-deftest python-end-of-defun-1 ()
+ (python-tests-with-temp-buffer
+ "
+class C:
+ def a(self
+ ):
+ pass
+
+ def b(self):
+ pass
+"
+ (should (= (save-excursion
+ (python-tests-look-at "def a")
+ (end-of-defun)
+ (point))
+ (save-excursion
+ (python-tests-look-at "def b")
+ (forward-line -1)
+ (point))))))
+
(ert-deftest python-nav-backward-defun-1 ()
(python-tests-with-temp-buffer
"
@@ -4330,6 +4396,101 @@ def foo():
(python-shell-interpreter "/some/path/to/bin/pypy"))
(should (python-shell-completion-native-interpreter-disabled-p))))
+(ert-deftest python-shell-completion-1 ()
+ (skip-unless (executable-find python-tests-shell-interpreter))
+ (python-tests-with-temp-buffer-with-shell
+ "
+import abc
+"
+ (let ((inhibit-message t))
+ (python-shell-send-buffer)
+ (python-tests-shell-wait-for-prompt)
+ (goto-char (point-max))
+ (insert "abc.")
+ (should (completion-at-point))
+ (insert "A")
+ (should (completion-at-point)))))
+
+(ert-deftest python-shell-completion-2 ()
+ "Should work regardless of the point in the Shell buffer."
+ (skip-unless (executable-find python-tests-shell-interpreter))
+ (python-tests-with-temp-buffer-with-shell
+ "
+import abc
+"
+ (let ((inhibit-message t))
+ (python-shell-send-buffer)
+ (python-tests-shell-wait-for-prompt)
+ (python-shell-with-shell-buffer
+ (goto-char (point-min)))
+ (goto-char (point-max))
+ (insert "abc.")
+ (should (completion-at-point)))))
+
+(ert-deftest python-shell-completion-native-1 ()
+ (skip-unless (executable-find python-tests-shell-interpreter))
+ (python-tests-with-temp-buffer-with-shell
+ "
+import abc
+"
+ (let ((inhibit-message t))
+ (python-shell-completion-native-turn-on)
+ (python-shell-send-buffer)
+ (python-tests-shell-wait-for-prompt)
+ (goto-char (point-max))
+ (insert "abc.")
+ (should (completion-at-point))
+ (insert "A")
+ (should (completion-at-point)))))
+
+(ert-deftest python-shell-completion-native-2 ()
+ "Should work regardless of the point in the Shell buffer."
+ (skip-unless (executable-find python-tests-shell-interpreter))
+ (python-tests-with-temp-buffer-with-shell
+ "
+import abc
+"
+ (let ((inhibit-message t))
+ (python-shell-completion-native-turn-on)
+ (python-shell-send-buffer)
+ (python-tests-shell-wait-for-prompt)
+ (python-shell-with-shell-buffer
+ (goto-char (point-min)))
+ (goto-char (point-max))
+ (insert "abc.")
+ (should (completion-at-point)))))
+
+(ert-deftest python-shell-completion-native-with-ffap-1 ()
+ (skip-unless (executable-find python-tests-shell-interpreter))
+ (python-tests-with-temp-buffer-with-shell
+ "
+import abc
+"
+ (let ((inhibit-message t))
+ (python-shell-completion-native-turn-on)
+ (python-shell-send-buffer)
+ (python-tests-shell-wait-for-prompt)
+ (goto-char (point-max))
+ (insert "abc.")
+ ;; This is called when FFAP is enabled and a find-file function is called.
+ (python-ffap-module-path "abc.")
+ (should (completion-at-point)))))
+
+(ert-deftest python-shell-completion-native-with-eldoc-1 ()
+ (skip-unless (executable-find python-tests-shell-interpreter))
+ (python-tests-with-temp-buffer-with-shell
+ "
+import abc
+"
+ (let ((inhibit-message t))
+ (python-shell-completion-native-turn-on)
+ (python-shell-send-buffer)
+ (python-tests-shell-wait-for-prompt)
+ (goto-char (point-max))
+ (insert "abc.")
+ ;; This is called by idle-timer when ElDoc is enabled.
+ (python-eldoc-function)
+ (should (completion-at-point)))))
@@ -5734,6 +5895,19 @@ def \\
(should (not (python-info-looking-at-beginning-of-defun)))
(should (not (python-info-looking-at-beginning-of-defun nil t)))))
+(ert-deftest python-info-looking-at-beginning-of-defun-3 ()
+ (python-tests-with-temp-buffer
+ "
+def foo(arg=\"default\"): # Comment
+ pass
+"
+ (python-tests-look-at "arg")
+ (should (python-info-looking-at-beginning-of-defun))
+ (python-tests-look-at "default")
+ (should (python-info-looking-at-beginning-of-defun))
+ (python-tests-look-at "Comment")
+ (should (python-info-looking-at-beginning-of-defun))))
+
(ert-deftest python-info-looking-at-beginning-of-block-1 ()
(python-tests-with-temp-buffer
"
diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
index 0c206b1e0c2..f39489071ec 100644
--- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb
+++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
@@ -177,11 +177,11 @@ qux :+,
b = $:
c = ??
-# Example from http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html
+# Example from https://ruby-doc.com/docs/ProgrammingRuby/
d = 4 + 5 + # no '\' needed
6 + 7
-# Example from http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html
+# Example from https://www.ruby-doc.org/docs/ProgrammingRuby/
e = 8 + 9 \
+ 10 # '\' needed
diff --git a/test/lisp/so-long-tests/so-long-tests-helpers.el b/test/lisp/so-long-tests/so-long-tests-helpers.el
index 852e7811cc3..79df532f899 100644
--- a/test/lisp/so-long-tests/so-long-tests-helpers.el
+++ b/test/lisp/so-long-tests/so-long-tests-helpers.el
@@ -41,14 +41,14 @@
(should (eq so-long--active t))
;; pcase fails here in Emacs 24.
(cl-case action
- ('so-long-mode
+ (so-long-mode
(should (eq major-mode 'so-long-mode))
(so-long-tests-assert-overrides)
(so-long-tests-assert-preserved))
- ('so-long-minor-mode
+ (so-long-minor-mode
(should (eq so-long-minor-mode t))
(so-long-tests-assert-overrides))
- ('longlines-mode
+ (longlines-mode
(should (eq longlines-mode t))))))
(defun so-long-tests-assert-reverted (action)
@@ -61,14 +61,14 @@
(should (eq so-long--active nil))
;; pcase fails here in Emacs 24.
(cl-case action
- ('so-long-mode
+ (so-long-mode
(should-not (eq major-mode 'so-long-mode))
(so-long-tests-assert-overrides-reverted)
(so-long-tests-assert-preserved))
- ('so-long-minor-mode
+ (so-long-minor-mode
(should-not (eq so-long-minor-mode t))
(so-long-tests-assert-overrides-reverted))
- ('longlines-mode
+ (longlines-mode
(should-not (eq longlines-mode t))))))
(defun so-long-tests-assert-and-revert (action)
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 30117132101..347981e8185 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -1158,5 +1158,13 @@ final or penultimate step during initialization."))
(should (equal (butlast l n)
(subr-tests--butlast-ref l n))))))
+(ert-deftest test-list-of-strings-p ()
+ (should-not (list-of-strings-p 1))
+ (should (list-of-strings-p nil))
+ (should (list-of-strings-p '("a" "b")))
+ (should-not (list-of-strings-p ["a" "b"]))
+ (should-not (list-of-strings-p '("a" nil "b")))
+ (should-not (list-of-strings-p '("a" "b" . "c"))))
+
(provide 'subr-tests)
;;; subr-tests.el ends here
diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el
index 55e37b71d80..1b5ef04436d 100644
--- a/test/lisp/time-stamp-tests.el
+++ b/test/lisp/time-stamp-tests.el
@@ -89,11 +89,11 @@
(iter-defun time-stamp-test-pattern-sequential ()
"Iterate through each possibility for a part of `time-stamp-pattern'."
(let ((pattern-value-parts
- '(("4/" "10/" "-4/" "0/" "") ;0: line limit
+ '(("4/" "10/" "-9/" "0/" "") ;0: line limit
("stamp<" "") ;1: start
- ("%-d" "%_H" "%^a" "%#Z" "%:A" "%02H" "%%" "") ;2: format part 1
+ ("%-d" "%_H" "%^a" "%#Z" "%:A" "%09z" "%%" "") ;2: format part 1
(" " "x" ":" "\n" "") ;3: format part 2
- ("%-d" "%_H" "%^a" "%#Z" "%:A" "%02H" "%%") ;4: format part 3
+ ("%-d" "%_H" "%^a" "%#Z" "%:A" "%09z" "%%") ;4: format part 3
(">end" "")))) ;5: end
(dotimes (cur (length pattern-value-parts))
(dotimes (cur-index (length (nth cur pattern-value-parts)))
@@ -118,7 +118,7 @@
(iter-defun time-stamp-test-pattern-multiply ()
"Iterate through every combination of parts of `time-stamp-pattern'."
(let ((line-limit-values '("" "4/"))
- (start-values '("" "stamp<"))
+ (start-values '("" "/stamp/"))
(format-values '("%%" "%m"))
(end-values '("" ">end")))
;; yield all combinations of the above
diff --git a/test/lisp/whitespace-tests.el b/test/lisp/whitespace-tests.el
index 792e157ec08..fb53543c9e1 100644
--- a/test/lisp/whitespace-tests.el
+++ b/test/lisp/whitespace-tests.el
@@ -27,7 +27,8 @@
(defmacro whitespace-tests--with-test-buffer (style &rest body)
"Run BODY in a buffer with `whitespace-mode' style STYLE.
The buffer is displayed in `selected-window', and
-`noninteractive' is set to nil even in batch mode."
+`noninteractive' is set to nil even in batch mode. If STYLE is
+nil, `whitespace-mode' is left disabled."
(declare (debug ((style form) def-body))
(indent 1))
`(ert-with-test-buffer-selected ()
@@ -37,7 +38,8 @@ The buffer is displayed in `selected-window', and
(let ((noninteractive nil)
(whitespace-style ,style))
(font-lock-mode 1)
- (whitespace-mode 1)
+ ,(when style
+ '(whitespace-mode 1))
,@body)))
(defun whitespace-tests--faceup (&rest lines)
@@ -149,7 +151,7 @@ buffer's content."
"»\t\n"
"\n"
" x"))
- (execute-kbd-macro (kbd "<up> <home>"))
+ (execute-kbd-macro (kbd "<up> C-a"))
(should (equal (point) 1))
(should (whitespace-tests--faceup " \n"
"\t\n"
@@ -187,7 +189,7 @@ buffer's content."
"» x"))
;; Inserting content on line 2 should un-highlight lines 2 and 3.
- (execute-kbd-macro (kbd "<up> <up> <end>"))
+ (execute-kbd-macro (kbd "<up> <up> C-e"))
(should (equal (line-number-at-pos) 2))
(should (equal (- (point) (line-beginning-position)) 1))
(execute-kbd-macro (kbd "y <down> <down>"))
@@ -199,7 +201,7 @@ buffer's content."
;; Removing the content on line 2 should re-highlight lines 2 and
;; 3.
- (execute-kbd-macro (kbd "<up> <up> <end>"))
+ (execute-kbd-macro (kbd "<up> <up> C-e"))
(should (equal (line-number-at-pos) 2))
(should (equal (- (point) (line-beginning-position)) 2))
(execute-kbd-macro (kbd "DEL <down> <down>"))
@@ -288,7 +290,7 @@ buffer's content."
" »"))
;; Inserting content on line 3 should un-highlight lines 2 and 3.
- (execute-kbd-macro (kbd "<down> <down> <home>"))
+ (execute-kbd-macro (kbd "<down> <down> C-a"))
(should (equal (line-number-at-pos) 3))
(should (equal (- (point) (line-beginning-position)) 0))
(execute-kbd-macro (kbd "y <up> <up>"))
@@ -300,7 +302,7 @@ buffer's content."
;; Removing the content on line 3 should re-highlight lines 2 and
;; 3.
- (execute-kbd-macro (kbd "<down> <down> <home>"))
+ (execute-kbd-macro (kbd "<down> <down> C-a"))
(should (equal (line-number-at-pos) 3))
(should (equal (- (point) (line-beginning-position)) 0))
(execute-kbd-macro (kbd "<deletechar> <up> <up>"))
@@ -310,6 +312,21 @@ buffer's content."
"\t\n"
" »"))))
+(ert-deftest whitespace-tests--empty-bob-eob-read-only-buffer ()
+ (whitespace-tests--with-test-buffer '()
+ (insert "\nx\n\n")
+ (should (equal (buffer-string) "\nx\n\n"))
+ (setq-local buffer-read-only t)
+ (goto-char 2)
+ (should (equal (line-number-at-pos) 2))
+ (should (equal (- (point) (line-beginning-position)) 0))
+ (let ((whitespace-style '(face empty)))
+ (whitespace-mode 1)
+ (should (whitespace-tests--faceup "«:whitespace-empty:\n"
+ "»x\n"
+ "«:whitespace-empty:\n"
+ "»")))))
+
(provide 'whitespace-tests)
;;; whitespace-tests.el ends here
diff --git a/test/lisp/xdg-tests.el b/test/lisp/xdg-tests.el
index e8e103348b7..882160743a2 100644
--- a/test/lisp/xdg-tests.el
+++ b/test/lisp/xdg-tests.el
@@ -59,6 +59,16 @@
(should (equal (xdg-desktop-strings " ") nil))
(should (equal (xdg-desktop-strings "a; ;") '("a" " "))))
+(ert-deftest xdg-current-desktop ()
+ (let ((env (getenv "XDG_CURRENT_DESKTOP")))
+ (unwind-protect
+ (progn
+ (setenv "XDG_CURRENT_DESKTOP" "KDE")
+ (should (equal (xdg-current-desktop) '("KDE")))
+ (setenv "XDG_CURRENT_DESKTOP" "ubuntu:GNOME")
+ (should (equal (xdg-current-desktop) '("ubuntu" "GNOME"))))
+ (setenv "XDG_CURRENT_DESKTOP" env))))
+
(ert-deftest xdg-mime-associations ()
"Test reading MIME associations from files."
(let* ((apps (ert-resource-file "mimeapps.list"))
diff --git a/test/manual/BidiCharacterTest.txt b/test/manual/BidiCharacterTest.txt
index c30d0778612..619d4b4412b 100644
--- a/test/manual/BidiCharacterTest.txt
+++ b/test/manual/BidiCharacterTest.txt
@@ -1,14 +1,14 @@
-# BidiCharacterTest-14.0.0.txt
-# Date: 2020-03-30, 23:56:00 GMT [LI]
-# © 2020 Unicode®, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# BidiCharacterTest-15.0.0.txt
+# Date: 2022-05-03, 18:46:00 GMT [LI]
+# © 2022 Unicode®, Inc.
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
+# For documentation, see https://www.unicode.org/reports/tr44/
#
# This file provides a conformance test for implementations of the
# Unicode Bidirectional Algorithm, specified in UAX #9: Unicode
-# Bidirectional Algorithm, at http://www.unicode.org/reports/tr9/
+# Bidirectional Algorithm, at https://www.unicode.org/reports/tr9/
#
# The test data has been generated with a few constraints. Each test case
# is a single paragraph, so the test data does not contain any characters
diff --git a/test/manual/image-circular-tests.el b/test/manual/image-circular-tests.el
index 1299970f827..d2187cbbadc 100644
--- a/test/manual/image-circular-tests.el
+++ b/test/manual/image-circular-tests.el
@@ -27,8 +27,11 @@
(require 'ert)
+(declare-function image-size "image.c" (spec &optional pixels frame))
+
(ert-deftest image-test-duplicate-keywords ()
"Test that duplicate keywords in an image spec lead to rejection."
+ (skip-unless (display-images-p))
(should-error (image-size `(image :type xbm :type xbm
:data-width 1 :data-height 1
:data ,(bool-vector t))
@@ -36,33 +39,37 @@
(ert-deftest image-test-circular-plist ()
"Test that a circular image spec is rejected."
- (should-error
- (let ((l `(image :type xbm :data-width 1 :data-height 1
- :data ,(bool-vector t))))
- (setcdr (last l) '#1=(:invalid . #1#))
- (image-size l t))))
+ (skip-unless (display-images-p))
+ (let ((spec `(image :type xbm :data-width 1 :data-height 1
+ :data ,(bool-vector t)
+ . ,'#1=(:invalid . #1#))))
+ (should-error (image-size spec t))))
(ert-deftest image-test-:type-property-value ()
"Test that :type is allowed as a property value in an image spec."
+ (skip-unless (display-images-p))
(should (equal (image-size `(image :dummy :type :type xbm
:data-width 1 :data-height 1
:data ,(bool-vector t))
t)
- (cons 1 1))))
+ '(1 . 1))))
(ert-deftest image-test-circular-specs ()
- "Test that circular image spec property values do not cause infinite recursion."
- (should
- (let* ((circ1 (cons :dummy nil))
- (circ2 (cons :dummy nil))
- (spec1 `(image :type xbm :data-width 1 :data-height 1
- :data ,(bool-vector 1) :ignored ,circ1))
- (spec2 `(image :type xbm :data-width 1 :data-height 1
+ "Test with circular image spec property values.
+In particular, test that they do not cause infinite recursion."
+ :expected-result :failed ;; FIXME: bug#36403#63.
+ (skip-unless (display-images-p))
+ ;; Two copies needed to warm up image cache.
+ (let* ((circ1 (list :dummy))
+ (circ2 (list :dummy))
+ (spec1 `(image :type xbm :data-width 1 :data-height 1
+ :data ,(bool-vector 1) :ignored ,circ1))
+ (spec2 `(image :type xbm :data-width 1 :data-height 1
:data ,(bool-vector 1) :ignored ,circ2)))
- (setcdr circ1 circ1)
- (setcdr circ2 circ2)
- (and (equal (image-size spec1 t) (cons 1 1))
- (equal (image-size spec2 t) (cons 1 1))))))
+ (setcdr circ1 circ1)
+ (setcdr circ2 circ2)
+ (should (equal (image-size spec1 t) '(1 . 1)))
+ (should (equal (image-size spec2 t) '(1 . 1)))))
(provide 'image-circular-tests)
;;; image-circular-tests.el ends here.
diff --git a/test/manual/image-tests.el b/test/manual/image-tests.el
index f867047d08e..400657132c7 100644
--- a/test/manual/image-tests.el
+++ b/test/manual/image-tests.el
@@ -32,9 +32,9 @@
;;; Code:
(defmacro image-skip-unless (format &rest condition)
- `(skip-unless (or (and (display-images-p)
- (image-type-available-p ,format))
- ,@condition)))
+ `(skip-unless (and (and (display-images-p)
+ (image-type-available-p ,format))
+ ,@condition)))
(defconst image-tests--images
`((gif . ,(expand-file-name "test/data/image/black.gif"
@@ -79,6 +79,21 @@
(image-tests-make-load-image-test 'xbm)
(image-tests-make-load-image-test 'xpm)
+(ert-deftest image-tests-load-image/svg-too-big ()
+ (with-temp-buffer
+ (let* ((max-image-size 0)
+ (messages-buffer-name (buffer-name (current-buffer)))
+ (img (cdr (assq 'svg image-tests--images)))
+ (file (if (listp img)
+ (plist-get (cdr img) :file)
+ img)))
+ (save-excursion (find-file file))
+ (should (string-match-p "invalid image size" (buffer-string)))
+ ;; no annoying newlines
+ (should-not (string-match-p "^[ \t\n\r]+$" (buffer-string)))
+ ;; no annoying double error reporting
+ (should-not (string-match-p "error parsing" (buffer-string))))))
+
(ert-deftest image-tests-load-image/svg-invalid ()
(with-temp-buffer
(let ((messages-buffer-name (buffer-name (current-buffer))))
@@ -90,7 +105,9 @@
:type svg)))
(redisplay))
;; librsvg error: "... Start tag expected, '<' not found [3 times]"
- (should (string-match "[Ee]rror.+Start tag expected" (buffer-string))))))
+ (should (string-match-p "[Ee]rror.+Start tag expected" (buffer-string)))
+ ;; no annoying newlines
+ (should-not (string-match-p "^[ \t\n\r]+$" (buffer-string))))))
;;;; image-test-size
@@ -222,7 +239,8 @@
;; contain metadata.
(ert-deftest image-tests-image-metadata/gif ()
- (image-skip-unless 'gif (not w32-use-native-image-API))
+ (image-skip-unless 'gif
+ (not (bound-and-true-p w32-use-native-image-API)))
(should (memq 'delay
(image-metadata
(create-image (cdr (assq 'gif image-tests--images)))))))
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index 1b239cec795..1edbd1777c6 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -860,21 +860,26 @@ Return a list of results."
(cl-eval-when (compile eval load)
(defconst comp-tests-type-spec-tests
- `(
+ ;; Why we quote everything here, you ask? So that values of
+ ;; `most-positive-fixnum' and `most-negative-fixnum', which can be
+ ;; architecture-dependent, do not end up hardcoded in the
+ ;; resulting byte-compiled file, and thus we could run the same
+ ;; .elc file on several architectures without fear.
+ '(
;; 1
((defun comp-tests-ret-type-spec-f (x)
x)
- t)
+ 't)
;; 2
((defun comp-tests-ret-type-spec-f ()
1)
- (integer 1 1))
+ '(integer 1 1))
;; 3
((defun comp-tests-ret-type-spec-f (x)
(if x 1 3))
- (or (integer 1 1) (integer 3 3)))
+ '(or (integer 1 1) (integer 3 3)))
;; 4
((defun comp-tests-ret-type-spec-f (x)
@@ -883,7 +888,7 @@ Return a list of results."
(setf y 1)
(setf y 2))
y))
- (integer 1 2))
+ '(integer 1 2))
;; 5
((defun comp-tests-ret-type-spec-f (x)
@@ -892,73 +897,73 @@ Return a list of results."
(setf y 1)
(setf y 3))
y))
- (or (integer 1 1) (integer 3 3)))
+ '(or (integer 1 1) (integer 3 3)))
;; 6
((defun comp-tests-ret-type-spec-f (x)
(if x
(list x)
3))
- (or cons (integer 3 3)))
+ '(or cons (integer 3 3)))
;; 7
((defun comp-tests-ret-type-spec-f (x)
(if x
'foo
3))
- (or (member foo) (integer 3 3)))
+ '(or (member foo) (integer 3 3)))
;; 8
((defun comp-tests-ret-type-spec-f (x)
(if (eq x 3)
x
'foo))
- (or (member foo) (integer 3 3)))
+ '(or (member foo) (integer 3 3)))
;; 9
((defun comp-tests-ret-type-spec-f (x)
(if (eq 3 x)
x
'foo))
- (or (member foo) (integer 3 3)))
+ '(or (member foo) (integer 3 3)))
;; 10
((defun comp-tests-ret-type-spec-f (x)
(if (eql x 3)
x
'foo))
- (or (member foo) (integer 3 3)))
+ '(or (member foo) (integer 3 3)))
;; 11
((defun comp-tests-ret-type-spec-f (x)
(if (eql 3 x)
x
'foo))
- (or (member foo) (integer 3 3)))
+ '(or (member foo) (integer 3 3)))
;; 12
((defun comp-tests-ret-type-spec-f (x)
(if (eql x 3)
'foo
x))
- (not (integer 3 3)))
+ '(not (integer 3 3)))
;; 13
((defun comp-tests-ret-type-spec-f (x y)
(if (= x y)
x
'foo))
- (or (member foo) marker number))
+ '(or (member foo) marker number))
;; 14
((defun comp-tests-ret-type-spec-f (x)
(comp-hint-fixnum x))
- (integer ,most-negative-fixnum ,most-positive-fixnum))
+ `(integer ,most-negative-fixnum ,most-positive-fixnum))
;; 15
((defun comp-tests-ret-type-spec-f (x)
(comp-hint-cons x))
- cons)
+ 'cons)
;; 16
((defun comp-tests-ret-type-spec-f (x)
@@ -966,7 +971,7 @@ Return a list of results."
(when x
(setf y 4))
y))
- (or null (integer 4 4)))
+ '(or null (integer 4 4)))
;; 17
((defun comp-tests-ret-type-spec-f ()
@@ -974,7 +979,7 @@ Return a list of results."
(y 3))
(setf x y)
y))
- (integer 3 3))
+ '(integer 3 3))
;; 18
((defun comp-tests-ret-type-spec-f (x)
@@ -982,120 +987,120 @@ Return a list of results."
(when x
(setf y x))
y))
- t)
+ 't)
;; 19
((defun comp-tests-ret-type-spec-f (x y)
(eq x y))
- boolean)
+ 'boolean)
;; 20
((defun comp-tests-ret-type-spec-f (x)
(when x
'foo))
- (or (member foo) null))
+ '(or (member foo) null))
;; 21
((defun comp-tests-ret-type-spec-f (x)
(unless x
'foo))
- (or (member foo) null))
+ '(or (member foo) null))
;; 22
((defun comp-tests-ret-type-spec-f (x)
(when (> x 3)
x))
- (or null float (integer 4 *)))
+ '(or null float (integer 4 *)))
;; 23
((defun comp-tests-ret-type-spec-f (x)
(when (>= x 3)
x))
- (or null float (integer 3 *)))
+ '(or null float (integer 3 *)))
;; 24
((defun comp-tests-ret-type-spec-f (x)
(when (< x 3)
x))
- (or null float (integer * 2)))
+ '(or null float (integer * 2)))
;; 25
((defun comp-tests-ret-type-spec-f (x)
(when (<= x 3)
x))
- (or null float (integer * 3)))
+ '(or null float (integer * 3)))
;; 26
((defun comp-tests-ret-type-spec-f (x)
(when (> 3 x)
x))
- (or null float (integer * 2)))
+ '(or null float (integer * 2)))
;; 27
((defun comp-tests-ret-type-spec-f (x)
(when (>= 3 x)
x))
- (or null float (integer * 3)))
+ '(or null float (integer * 3)))
;; 28
((defun comp-tests-ret-type-spec-f (x)
(when (< 3 x)
x))
- (or null float (integer 4 *)))
+ '(or null float (integer 4 *)))
;; 29
((defun comp-tests-ret-type-spec-f (x)
(when (<= 3 x)
x))
- (or null float (integer 3 *)))
+ '(or null float (integer 3 *)))
;; 30
((defun comp-tests-ret-type-spec-f (x)
(let ((y 3))
(when (> x y)
x)))
- (or null float (integer 4 *)))
+ '(or null float (integer 4 *)))
;; 31
((defun comp-tests-ret-type-spec-f (x)
(let ((y 3))
(when (> y x)
x)))
- (or null float (integer * 2)))
+ '(or null float (integer * 2)))
;; 32
((defun comp-tests-ret-type-spec-f (x)
(when (and (> x 3)
(< x 10))
x))
- (or null float (integer 4 9)))
+ '(or null float (integer 4 9)))
;; 33
((defun comp-tests-ret-type-spec-f (x)
(when (or (> x 3)
(< x 10))
x))
- (or null float integer))
+ '(or null float integer))
;; 34
((defun comp-tests-ret-type-spec-f (x)
(when (or (< x 3)
(> x 10))
x))
- (or null float (integer * 2) (integer 11 *)))
+ '(or null float (integer * 2) (integer 11 *)))
;; 35 No float range support.
((defun comp-tests-ret-type-spec-f (x)
(when (> x 1.0)
x))
- (or null marker number))
+ '(or null marker number))
;; 36
((defun comp-tests-ret-type-spec-f (x y)
(when (and (> x 3)
(> y 2))
(+ x y)))
- (or null float (integer 7 *)))
+ '(or null float (integer 7 *)))
;; 37
;; SBCL: (OR REAL NULL)
@@ -1103,14 +1108,14 @@ Return a list of results."
(when (and (<= x 3)
(<= y 2))
(+ x y)))
- (or null float (integer * 5)))
+ '(or null float (integer * 5)))
;; 38
((defun comp-tests-ret-type-spec-f (x y)
(when (and (< 1 x 5)
(< 1 y 5))
(+ x y)))
- (or null float (integer 4 8)))
+ '(or null float (integer 4 8)))
;; 39
;; SBCL gives: (OR REAL NULL)
@@ -1118,7 +1123,7 @@ Return a list of results."
(when (and (<= 1 x 10)
(<= 2 y 3))
(+ x y)))
- (or null float (integer 3 13)))
+ '(or null float (integer 3 13)))
;; 40
;; SBCL: (OR REAL NULL)
@@ -1126,42 +1131,42 @@ Return a list of results."
(when (and (<= 1 x 10)
(<= 2 y 3))
(- x y)))
- (or null float (integer -2 8)))
+ '(or null float (integer -2 8)))
;; 41
((defun comp-tests-ret-type-spec-f (x y)
(when (and (<= 1 x)
(<= 2 y 3))
(- x y)))
- (or null float (integer -2 *)))
+ '(or null float (integer -2 *)))
;; 42
((defun comp-tests-ret-type-spec-f (x y)
(when (and (<= 1 x 10)
(<= 2 y))
(- x y)))
- (or null float (integer * 8)))
+ '(or null float (integer * 8)))
;; 43
((defun comp-tests-ret-type-spec-f (x y)
(when (and (<= x 10)
(<= 2 y))
(- x y)))
- (or null float (integer * 8)))
+ '(or null float (integer * 8)))
;; 44
((defun comp-tests-ret-type-spec-f (x y)
(when (and (<= x 10)
(<= y 3))
(- x y)))
- (or null float integer))
+ '(or null float integer))
;; 45
((defun comp-tests-ret-type-spec-f (x y)
(when (and (<= 2 x)
(<= 3 y))
(- x y)))
- (or null float integer))
+ '(or null float integer))
;; 46
;; SBCL: (OR (RATIONAL (6) (30)) (SINGLE-FLOAT 6.0 30.0)
@@ -1174,63 +1179,63 @@ Return a list of results."
(< 1 j 5)
(< 1 k 5))
(+ x y z i j k)))
- (or null float (integer 12 24)))
+ '(or null float (integer 12 24)))
;; 47
((defun comp-tests-ret-type-spec-f (x)
(when (<= 1 x 5)
(1+ x)))
- (or null float (integer 2 6)))
+ '(or null float (integer 2 6)))
;;48
((defun comp-tests-ret-type-spec-f (x)
(when (<= 1 x 5)
(1- x)))
- (or null float (integer 0 4)))
+ '(or null float (integer 0 4)))
;; 49
((defun comp-tests-ret-type-spec-f ()
(error "Foo"))
- nil)
+ 'nil)
;; 50
((defun comp-tests-ret-type-spec-f (x)
(if (stringp x)
x
'bar))
- (or (member bar) string))
+ '(or (member bar) string))
;; 51
((defun comp-tests-ret-type-spec-f (x)
(if (stringp x)
'bar
x))
- (not string))
+ '(not string))
;; 52
((defun comp-tests-ret-type-spec-f (x)
(if (integerp x)
x
'bar))
- (or (member bar) integer))
+ '(or (member bar) integer))
;; 53
((defun comp-tests-ret-type-spec-f (x)
(when (integerp x)
x))
- (or null integer))
+ '(or null integer))
;; 54
((defun comp-tests-ret-type-spec-f (x)
(unless (symbolp x)
x))
- t)
+ 't)
;; 55
((defun comp-tests-ret-type-spec-f (x)
(unless (integerp x)
x))
- (not integer))
+ '(not integer))
;; 56
((defun comp-tests-ret-type-spec-f (x)
@@ -1238,7 +1243,7 @@ Return a list of results."
(1 (message "one"))
(5 (message "five")))
x)
- t
+ 't
;; FIXME improve `comp-cond-cstrs-target-mvar' to cross block
;; boundary if necessary as this should return:
;; (or (integer 1 1) (integer 5 5))
@@ -1250,7 +1255,7 @@ Return a list of results."
(eql x 3))
(error "Not foo or 3"))
x)
- (or (member foo) (integer 3 3)))
+ '(or (member foo) (integer 3 3)))
;;58
((defun comp-tests-ret-type-spec-f (x y)
@@ -1259,7 +1264,7 @@ Return a list of results."
(<= x y))
x
(error "")))
- (integer 0 *))
+ '(integer 0 *))
;; 59
((defun comp-tests-ret-type-spec-f (x y)
@@ -1268,7 +1273,7 @@ Return a list of results."
(<= x y))
x
(error "")))
- (or float (integer 3 10)))
+ '(or float (integer 3 10)))
;; 60
((defun comp-tests-ret-type-spec-f (x y)
@@ -1277,56 +1282,56 @@ Return a list of results."
(>= x y))
x
(error "")))
- (or float (integer 3 10)))
+ '(or float (integer 3 10)))
;; 61
((defun comp-tests-ret-type-spec-f (x)
(if (= x 1.0)
x
(error "")))
- (or (member 1.0) (integer 1 1)))
+ '(or (member 1.0) (integer 1 1)))
;; 62
((defun comp-tests-ret-type-spec-f (x)
(if (= x 1.0)
x
(error "")))
- (or (member 1.0) (integer 1 1)))
+ '(or (member 1.0) (integer 1 1)))
;; 63
((defun comp-tests-ret-type-spec-f (x)
(if (= x 1.1)
x
(error "")))
- (member 1.1))
+ '(member 1.1))
;; 64
((defun comp-tests-ret-type-spec-f (x)
(if (= x 1)
x
(error "")))
- (or (member 1.0) (integer 1 1)))
+ '(or (member 1.0) (integer 1 1)))
;; 65
((defun comp-tests-ret-type-spec-f (x)
(if (= x 1)
x
(error "")))
- (or (member 1.0) (integer 1 1)))
+ '(or (member 1.0) (integer 1 1)))
;; 66
((defun comp-tests-ret-type-spec-f (x)
(if (eql x 0.0)
x
(error "")))
- float)
+ 'float)
;; 67
((defun comp-tests-ret-type-spec-f (x)
(if (equal x '(1 2 3))
x
(error "")))
- cons)
+ 'cons)
;; 68
((defun comp-tests-ret-type-spec-f (x)
@@ -1335,7 +1340,7 @@ Return a list of results."
x
(error "")))
;; Conservative (see cstr relax in `comp-cstr-=').
- (or (member 1.0) (integer 1 1)))
+ '(or (member 1.0) (integer 1 1)))
;; 69
((defun comp-tests-ret-type-spec-f (x)
@@ -1344,7 +1349,7 @@ Return a list of results."
x
(error "")))
;; Conservative (see cstr relax in `comp-cstr-=').
- (or (member 1.0) (integer 1 1)))
+ '(or (member 1.0) (integer 1 1)))
;; 70
((defun comp-tests-ret-type-spec-f (x y)
@@ -1353,14 +1358,14 @@ Return a list of results."
(= x y))
x
(error "")))
- (or float integer))
+ '(or float integer))
;; 71
((defun comp-tests-ret-type-spec-f (x)
(if (= x 0.0)
x
(error "")))
- (or (member -0.0 0.0) (integer 0 0)))
+ '(or (member -0.0 0.0) (integer 0 0)))
;; 72
((defun comp-tests-ret-type-spec-f (x)
@@ -1369,27 +1374,27 @@ Return a list of results."
(unless (eql x -0.0)
(error ""))
x)
- float)
+ 'float)
;; 73
((defun comp-tests-ret-type-spec-f (x)
(when (eql x 1.0)
(error ""))
x)
- t)
+ 't)
;; 74
((defun comp-tests-ret-type-spec-f (x)
(if (eq x 0)
(error "")
(1+ x)))
- number)))
+ 'number)))
(defun comp-tests-define-type-spec-test (number x)
`(comp-deftest ,(intern (format "ret-type-spec-%d" number)) ()
,(format "Type specifier test number %d." number)
(let ((comp-ctxt (make-comp-cstr-ctxt)))
- (comp-tests-check-ret-type-spec ',(car x) ',(cadr x))))))
+ (comp-tests-check-ret-type-spec ',(car x) ,(cadr x))))))
(defmacro comp-tests-define-type-spec-tests ()
"Define all type specifier tests."
diff --git a/test/src/emacs-module-resources/mod-test.c b/test/src/emacs-module-resources/mod-test.c
index 187af821c22..b47a0b7a39b 100644
--- a/test/src/emacs-module-resources/mod-test.c
+++ b/test/src/emacs-module-resources/mod-test.c
@@ -24,7 +24,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <limits.h>
-#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el
index 1b2ad99360b..bb2f04e8ee1 100644
--- a/test/src/eval-tests.el
+++ b/test/src/eval-tests.el
@@ -108,26 +108,6 @@ Bug#24912."
(should-error (eval (cons 'cond clauses) nil))
(should-error (eval (cons 'cond clauses) t))))
-(defun eval-tests--exceed-specbind-limit ()
- (defvar eval-tests--var1)
- (defvar eval-tests--var2)
- ;; Bind two variables, to make extra sure we hit the
- ;; `max-specpdl-size' limit before the `max-lisp-eval-depth' limit.
- (let ((eval-tests--var1 1)
- (eval-tests--var2 2))
- ;; Recurse until we hit the limit.
- (eval-tests--exceed-specbind-limit)))
-
-(ert-deftest eval-exceed-specbind-with-signal-hook ()
- "Test for Bug#30481.
-Check that Emacs doesn't crash when exceeding specbind limit with
-`signal-hook-function' bound. NOTE: Without the fix for
-Bug#30481, this test can appear to pass, but cause a
-crash/abort/malloc assert failure on the next test."
- (let ((max-specpdl-size (/ max-lisp-eval-depth 2))
- (signal-hook-function #'ignore))
- (should-error (eval-tests--exceed-specbind-limit))))
-
(ert-deftest defvar/bug31072 ()
"Check that Bug#31072 is fixed."
(should-error (eval '(defvar 1) t) :type 'wrong-type-argument))
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el
index fe8df7097a7..5d5d497c997 100644
--- a/test/src/fns-tests.el
+++ b/test/src/fns-tests.el
@@ -131,47 +131,56 @@
(should (equal [t t t t t nil nil nil nil nil] (vconcat (nreverse A))))))
(defconst fns-tests--string-lessp-cases
- '((a 97 error)
- (97 "a" error)
- ("abc" "abd" t)
- ("abd" "abc" nil)
- (abc "abd" t)
- ("abd" abc nil)
- (abc abd t)
- (abd abc nil)
- ("" "" nil)
- ("" " " t)
- (" " "" nil)
- ("abc" "abcd" t)
- ("abcd" "abc" nil)
- ("abc" "abc" nil)
- (abc abc nil)
- ("\0" "" nil)
- ("" "\0" t)
- ("~" "\x80" t)
- ("\x80" "\x80" nil)
- ("\xfe" "\xff" t)
- ("Munchen" "München" t)
- ("München" "Munchen" nil)
- ("München" "München" nil)
- ("Ré" "Réunion" t)))
-
+ `(("abc" < "abd")
+ (abc < "abd")
+ (abc < abd)
+ ("" = "")
+ ("" < " ")
+ ("abc" < "abcd")
+ ("abc" = "abc")
+ (abc = abc)
+ ("" < "\0")
+ ("~" < "\x80")
+ ("\x80" = "\x80")
+ ("\xfe" < "\xff")
+ ("Munchen" < "München")
+ ("München" = "München")
+ ("Ré" < "Réunion")
+ ("abc" = ,(string-to-multibyte "abc"))
+ (,(string-to-multibyte "abc") = ,(string-to-multibyte "abc"))
+ ("abc" < ,(string-to-multibyte "abd"))
+ (,(string-to-multibyte "abc") < "abd")
+ (,(string-to-multibyte "abc") < ,(string-to-multibyte "abd"))
+ (,(string-to-multibyte "\x80") = ,(string-to-multibyte "\x80"))
+ ("Liberté, Égalité, Fraternité" = "Liberté, Égalité, Fraternité")
+ ("Liberté, Égalité, Fraternité" < "Liberté, Égalité, Sororité")
+
+ ;; Cases concerning the ordering of raw bytes: these are
+ ;; troublesome because the current `string<' order is not very useful as
+ ;; it equates unibyte 80..FF with multibyte U+0080..00FF, and is also
+ ;; inconsistent with `string=' (see bug#58168).
+ ;;("\x80" < ,(string-to-multibyte "\x80"))
+ ;;("\xff" < ,(string-to-multibyte "\x80"))
+ ;;("ü" < "\xfc")
+ ;;("ü" < ,(string-to-multibyte "\xfc"))
+ )
+ "List of (A REL B) where REL is the relation (`<' or `=') between A and B.")
(ert-deftest fns-tests-string-lessp ()
;; Exercise both `string-lessp' and its alias `string<', both directly
;; and in a function (exercising its bytecode).
- (dolist (lessp (list #'string-lessp #'string<
- (lambda (a b) (string-lessp a b))
- (lambda (a b) (string< a b))))
- (ert-info ((prin1-to-string lessp) :prefix "function: ")
+ (dolist (fun (list #'string-lessp #'string<
+ (lambda (a b) (string-lessp a b))
+ (lambda (a b) (string< a b))))
+ (ert-info ((prin1-to-string fun) :prefix "function: ")
+ (should-error (funcall fun 'a 97))
+ (should-error (funcall fun 97 "a"))
(dolist (case fns-tests--string-lessp-cases)
(ert-info ((prin1-to-string case) :prefix "case: ")
- (pcase case
- (`(,x ,y error)
- (should-error (funcall lessp x y)))
- (`(,x ,y ,expected)
- (should (equal (funcall lessp x y) expected)))))))))
-
+ (pcase-let ((`(,x ,rel ,y) case))
+ (cl-assert (memq rel '(< =)))
+ (should (equal (funcall fun x y) (eq rel '<)))
+ (should (equal (funcall fun y x) nil))))))))
(ert-deftest fns-tests-compare-strings ()
(should-error (compare-strings))
@@ -1422,4 +1431,31 @@
(should (equal (ntake (- most-negative-fixnum 1) list) nil))
(should (equal list '(a b c)))))
+(ert-deftest fns--copy-alist ()
+ (dolist (orig '(nil
+ ((a . 1) (b . 2) (a . 3))
+ (a (b . 3) ((c) (d)))))
+ (ert-info ((prin1-to-string orig) :prefix "orig: ")
+ (let ((copy (copy-alist orig)))
+ (should (equal orig copy))
+ (while orig
+ (should-not (eq orig copy))
+ ;; Check that cons pairs are copied but nothing else.
+ (let ((orig-elt (car orig))
+ (copy-elt (car copy)))
+ (if (atom orig-elt)
+ (should (eq orig-elt copy-elt))
+ (should-not (eq orig-elt copy-elt))
+ (should (eq (car orig-elt) (car copy-elt)))
+ (should (eq (cdr orig-elt) (cdr copy-elt)))))
+ (setq orig (cdr orig))
+ (setq copy (cdr copy))))))
+
+ (should-error (copy-alist 'a)
+ :type 'wrong-type-argument)
+ (should-error (copy-alist [(a . 1) (b . 2) (a . 3)])
+ :type 'wrong-type-argument)
+ (should-error (copy-alist "abc")
+ :type 'wrong-type-argument))
+
;;; fns-tests.el ends here
diff --git a/test/src/image-tests.el b/test/src/image-tests.el
index bf79faca52e..d1a4dad37b9 100644
--- a/test/src/image-tests.el
+++ b/test/src/image-tests.el
@@ -23,6 +23,10 @@
(require 'ert)
+(declare-function image-size "image.c" (spec &optional pixels frame))
+(declare-function image-mask-p "image.c" (spec &optional frame))
+(declare-function image-metadata "image.c" (spec &optional frame))
+
(defconst image-tests--images
`((gif . ,(expand-file-name "test/data/image/black.gif"
source-directory))
diff --git a/test/src/lcms-tests.el b/test/src/lcms-tests.el
index 1829a7ea1f1..7f0f660d13e 100644
--- a/test/src/lcms-tests.el
+++ b/test/src/lcms-tests.el
@@ -28,7 +28,7 @@
;; https://github.com/njsmith/colorspacious
;; Other references:
-;; http://www.babelcolor.com/index_htm_files/A%20review%20of%20RGB%20color%20spaces.pdf
+;; https://www.babelcolor.com/index_htm_files/A%20review%20of%20RGB%20color%20spaces.pdf
;;; Code:
diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el
index 5af43923012..be4f60ab57f 100644
--- a/test/src/sqlite-tests.el
+++ b/test/src/sqlite-tests.el
@@ -241,4 +241,17 @@
(should (multibyte-string-p c1))
(should-not (multibyte-string-p c2)))))))
+(ert-deftest sqlite-returning ()
+ (skip-unless (sqlite-available-p))
+ (let (db)
+ (progn
+ (setq db (sqlite-open))
+ (sqlite-execute db "CREATE TABLE people1 (people_id INTEGER PRIMARY KEY, first TEXT, last TEXT)")
+ (should (null (sqlite-select db "select * from people1")))
+ (should
+ (equal
+ (sqlite-execute db "INSERT INTO people1 (first, last) values (?, ?) RETURNING people_id, first"
+ '("Joe" "Doe"))
+ '((1 "Joe")))))))
+
;;; sqlite-tests.el ends here